java
Dalam artikel ini, kita akan belajar tentang ekspresi lambda Java dan penggunaan ekspresi lambda dengan antarmuka fungsional, antarmuka fungsional generik, dan API aliran dengan bantuan contoh.
Ekspresi lambda diperkenalkan pertama kali di Java 8. Tujuan utamanya untuk meningkatkan kekuatan ekspresif bahasa.
Namun, sebelum masuk ke lambda, pertama-tama kita perlu memahami antarmuka fungsional.
Jika antarmuka Java berisi satu dan hanya satu metode abstrak maka disebut antarmuka fungsional. Ini hanya satu metode yang menentukan tujuan antarmuka.
Misalnya, Runnable
antarmuka dari paket java.lang
; adalah antarmuka fungsional karena hanya terdiri dari satu metode yaitu run()
.
import java.lang.FunctionalInterface;
@FunctionalInterface
public interface MyInterface{
// the single abstract method
double getValue();
}
Dalam contoh di atas, antarmuka MyInterface hanya memiliki satu metode abstrak getValue(). Oleh karena itu, ini adalah antarmuka yang fungsional.
Di sini, kami telah menggunakan anotasi @FunctionalInterface
. Anotasi memaksa kompiler Java untuk menunjukkan bahwa antarmuka adalah antarmuka fungsional. Oleh karena itu, tidak memungkinkan untuk memiliki lebih dari satu metode abstrak. Namun, itu tidak wajib.
Di Java 7, antarmuka fungsional dianggap sebagai Metode Abstrak Tunggal atau SAM Tipe. SAM biasanya diimplementasikan dengan Kelas Anonim di Java 7.
public class FunctionInterfaceTest {
public static void main(String[] args) {
// anonymous class
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("I just implemented the Runnable Functional Interface.");
}
}).start();
}
}
Keluaran :
I just implemented the Runnable Functional Interface.
Di sini, kita dapat meneruskan kelas anonim ke suatu metode. Ini membantu untuk menulis program dengan lebih sedikit kode di Java 7. Namun, sintaksnya masih sulit dan banyak baris kode tambahan yang diperlukan.
Java 8 memperluas kekuatan SAM dengan melangkah lebih jauh. Karena kita tahu bahwa antarmuka fungsional hanya memiliki satu metode, seharusnya tidak perlu mendefinisikan nama metode itu saat meneruskannya sebagai argumen. Ekspresi Lambda memungkinkan kita melakukan hal itu.
Ekspresi Lambda pada dasarnya adalah metode anonim atau tanpa nama. Ekspresi lambda tidak dijalankan dengan sendirinya. Sebagai gantinya, ini digunakan untuk mengimplementasikan metode yang ditentukan oleh antarmuka fungsional.
Berikut adalah bagaimana kita dapat mendefinisikan ekspresi lambda di Java.
(parameter list) -> lambda body
Operator baru (->
) yang digunakan dikenal sebagai operator panah atau operator lambda. Sintaksnya mungkin tidak jelas saat ini. Mari kita jelajahi beberapa contoh,
Misalkan, kita memiliki metode seperti ini:
double getPiValue() {
return 3.1415;
}
Kita dapat menulis metode ini menggunakan ekspresi lambda sebagai:
() -> 3.1415
Di sini, metode tidak memiliki parameter apa pun. Oleh karena itu, sisi kiri operator menyertakan parameter kosong. Sisi kanan adalah badan lambda yang menentukan tindakan ekspresi lambda. Dalam hal ini, ia mengembalikan nilai 3.1415.
Di Jawa, tubuh lambda terdiri dari dua jenis.
1. Tubuh dengan satu ekspresi
() -> System.out.println("Lambdas are great");
Jenis badan lambda ini dikenal sebagai badan ekspresi.
2. Badan yang terdiri dari blok kode.
() -> {
double pi = 3.1415;
return pi;
};
Jenis badan lambda ini dikenal sebagai badan blok. Badan blok memungkinkan badan lambda untuk memasukkan beberapa pernyataan. Pernyataan ini diapit di dalam kurung kurawal dan Anda harus menambahkan titik koma setelah kurung kurawal.
Catatan :Untuk badan blok, Anda dapat memiliki pernyataan kembali jika badan mengembalikan nilai. Namun, badan ekspresi tidak memerlukan pernyataan kembali.
Mari kita tulis program Java yang mengembalikan nilai Pi menggunakan ekspresi lambda.
Seperti disebutkan sebelumnya, ekspresi lambda tidak dieksekusi sendiri. Sebaliknya, ini membentuk implementasi metode abstrak yang didefinisikan oleh antarmuka fungsional.
Jadi, kita perlu mendefinisikan antarmuka fungsional terlebih dahulu.
import java.lang.FunctionalInterface;
// this is functional interface
@FunctionalInterface
interface MyInterface{
// abstract method
double getPiValue();
}
public class Main {
public static void main( String[] args ) {
// declare a reference to MyInterface
MyInterface ref;
// lambda expression
ref = () -> 3.1415;
System.out.println("Value of Pi = " + ref.getPiValue());
}
}
Keluaran :
Value of Pi = 3.1415
Pada contoh di atas,
getPiValue()
// it will throw an error
MyInterface ref = new myInterface();
// it is valid
MyInterface ref;
ref = () -> 3.1415;
getPiValue()
menggunakan antarmuka referensi. Kapan
System.out.println("Value of Pi = " + ref.getPiValue());
Sampai sekarang kami telah membuat ekspresi lambda tanpa parameter apa pun. Namun, mirip dengan metode, ekspresi lambda juga dapat memiliki parameter. Misalnya,
(n) -> (n%2)==0
Di sini, variabel n di dalam kurung adalah parameter yang diteruskan ke ekspresi lambda. Badan lambda mengambil parameter dan memeriksa apakah itu genap atau ganjil.
@FunctionalInterface
interface MyInterface {
// abstract method
String reverse(String n);
}
public class Main {
public static void main( String[] args ) {
// declare a reference to MyInterface
// assign a lambda expression to the reference
MyInterface ref = (str) -> {
String result = "";
for (int i = str.length()-1; i >= 0 ; i--)
result += str.charAt(i);
return result;
};
// call the method of the interface
System.out.println("Lambda reversed = " + ref.reverse("Lambda"));
}
}
Keluaran :
Lambda reversed = adbmaL
Sampai sekarang kami telah menggunakan antarmuka fungsional yang hanya menerima satu jenis nilai. Misalnya,
@FunctionalInterface
interface MyInterface {
String reverseString(String n);
}
Antarmuka fungsional di atas hanya menerima String
dan mengembalikan String
. Namun, kita dapat membuat antarmuka fungsional menjadi generik, sehingga tipe data apa pun dapat diterima. Jika Anda tidak yakin tentang obat generik, kunjungi Java Generics.
// GenericInterface.java
@FunctionalInterface
interface GenericInterface<T> {
// generic method
T func(T t);
}
// GenericLambda.java
public class Main {
public static void main( String[] args ) {
// declare a reference to GenericInterface
// the GenericInterface operates on String data
// assign a lambda expression to it
GenericInterface<String> reverse = (str) -> {
String result = "";
for (int i = str.length()-1; i >= 0 ; i--)
result += str.charAt(i);
return result;
};
System.out.println("Lambda reversed = " + reverse.func("Lambda"));
// declare another reference to GenericInterface
// the GenericInterface operates on Integer data
// assign a lambda expression to it
GenericInterface<Integer> factorial = (n) -> {
int result = 1;
for (int i = 1; i <= n; i++)
result = i * result;
return result;
};
System.out.println("factorial of 5 = " + factorial.func(5));
}
}
Keluaran :
Lambda reversed = adbmaL factorial of 5 = 120
Dalam contoh di atas, kami telah membuat antarmuka fungsional generik bernama GenericInterface . Ini berisi metode generik bernama func()
.
Di sini, di dalam kelas Utama,
GenericInterface<String> reverse
- membuat referensi ke antarmuka. Antarmuka sekarang beroperasi pada String
jenis data.GenericInterface<Integer> factorial
- membuat referensi ke antarmuka. Antarmuka, dalam hal ini, beroperasi pada Integer
jenis data.
Paket java.util.stream baru telah ditambahkan ke JDK8 yang memungkinkan pengembang java untuk melakukan operasi seperti pencarian, filter, peta, pengurangan, atau manipulasi koleksi seperti Lists
.
Misalnya, kami memiliki aliran data (dalam kasus kami List
dari String
) di mana setiap string adalah kombinasi dari nama negara dan tempat negara. Sekarang, kami dapat memproses aliran data ini dan hanya mengambil tempat dari Nepal.
Untuk ini, kami dapat melakukan operasi massal di aliran dengan kombinasi Stream API dan ekspresi Lambda.
import java.util.ArrayList;
import java.util.List;
public class StreamMain {
// create an object of list using ArrayList
static List<String> places = new ArrayList<>();
// preparing our data
public static List getPlaces(){
// add places and country to the list
places.add("Nepal, Kathmandu");
places.add("Nepal, Pokhara");
places.add("India, Delhi");
places.add("USA, New York");
places.add("Africa, Nigeria");
return places;
}
public static void main( String[] args ) {
List<String> myPlaces = getPlaces();
System.out.println("Places from Nepal:");
// Filter places from Nepal
myPlaces.stream()
.filter((p) -> p.startsWith("Nepal"))
.map((p) -> p.toUpperCase())
.sorted()
.forEach((p) -> System.out.println(p));
}
}
Keluaran :
Places from Nepal: NEPAL, KATHMANDU NEPAL, POKHARA
Pada contoh di atas, perhatikan pernyataan,
myPlaces.stream()
.filter((p) -> p.startsWith("Nepal"))
.map((p) -> p.toUpperCase())
.sorted()
.forEach((p) -> System.out.println(p));
Di sini, kami menggunakan metode seperti filter()
, map()
dan forEach()
dari API Aliran. Metode ini dapat mengambil ekspresi lambda sebagai input.
Kita juga dapat mendefinisikan ekspresi kita sendiri berdasarkan sintaks yang kita pelajari di atas. Ini memungkinkan kita untuk mengurangi baris kode secara drastis seperti yang kita lihat pada contoh di atas.
java
Antarmuka Set Java Dalam tutorial ini, kita akan belajar tentang antarmuka Set di Java dan metodenya. Set antarmuka Java Collections framework menyediakan fitur dari himpunan matematika di Jawa. Ini memperluas Collection antarmuka. Berbeda dengan List antarmuka, set tidak boleh berisi elemen dupl
Antarmuka Java SortedSet Dalam tutorial ini, kita akan belajar tentang antarmuka SortedSet di Java dan metodenya dengan bantuan sebuah contoh. SortedSet antarmuka kerangka Java Collections digunakan untuk menyimpan elemen dengan beberapa urutan dalam satu set. Ini memperluas antarmuka Set. Kel
Antarmuka Iterator Java Dalam tutorial ini, kita akan belajar tentang antarmuka Java Iterator dengan bantuan sebuah contoh. Iterator antarmuka kerangka koleksi Java memungkinkan kita untuk mengakses elemen koleksi. Ini memiliki subinterface ListIterator . Semua koleksi Java menyertakan iterator
Antarmuka Java ListIterator Dalam tutorial ini, kita akan belajar tentang antarmuka Java ListIterator dengan bantuan sebuah contoh. ListIterator antarmuka kerangka koleksi Java menyediakan fungsionalitas untuk mengakses elemen daftar. Ini adalah dua arah. Ini berarti memungkinkan kita untuk mengu