Lambda & Stream API

Functional interface, ekspresi lambda, method reference, Stream (filter, map, reduce, collect), dan Optional.

Part 12 dari 17 ± 55 menit Gratis

Lambda: fungsi singkat

Sejak Java 8, kamu bisa menulis potongan perilaku sebagai nilai. Ekspresi lambda adalah method tanpa nama dengan sintaks (parameter) -> hasil.

// cara lama: kelas anonim
Comparator<String> lama = new Comparator<String>() {
    public int compare(String a, String b) { return a.length() - b.length(); }
};

// lambda
Comparator<String> baru = (a, b) -> a.length() - b.length();

Variasi penulisan:

x -> x * 2                    // satu parameter, tanpa kurung
(a, b) -> a + b               // dua parameter
() -> System.out.println("hi") // tanpa parameter
(a, b) -> {                   // beberapa baris: pakai kurung kurawal + return
    int s = a + b;
    return s * 2;
}

Functional interface

Lambda bisa dipakai di mana pun ada functional interface, yaitu interface dengan satu method abstrak. Yang sering dipakai (paket java.util.function):

InterfaceBentukContoh
Predicate<T>T → booleanx -> x > 5
Function<T,R>T → Rs -> s.length()
Consumer<T>T → (tidak ada)s -> System.out.println(s)
Supplier<T>() → T() -> "baru"
Runnable() → (tidak ada)() -> doWork()
Predicate<Integer> genap = n -> n % 2 == 0;
System.out.println(genap.test(4));   // true

Method reference

Jika lambda hanya memanggil satu method, tulis lebih ringkas dengan :::

nama.forEach(n -> System.out.println(n));
nama.forEach(System.out::println);          // sama
nama.stream().map(String::toUpperCase);     // s -> s.toUpperCase()

Stream API

Stream adalah aliran data yang diproses dengan rangkaian operasi (pipeline) tanpa mengubah sumbernya. Strukturnya: sumber → operasi perantara → operasi akhir.

List<Integer> angka = List.of(1, 2, 3, 4, 5, 6);

List<Integer> kuadratGenap = angka.stream()
        .filter(n -> n % 2 == 0)     // saring: 2, 4, 6
        .map(n -> n * n)             // ubah: 4, 16, 36
        .toList();                    // kumpulkan (Java 16+)

System.out.println(kuadratGenap);   // [4, 16, 36]
OperasiJenisFungsi
filter(Predicate)perantaramenyaring elemen
map(Function)perantaramengubah tiap elemen
sorted()perantaramengurutkan
distinct(), limit(n)perantarabuang duplikat, ambil n pertama
forEach(Consumer)akhirmenjalankan aksi per elemen
count()akhirjumlah elemen
sum(), average(), max()akhir (stream angka)agregasi
reduce(...)akhirmenggabung jadi satu nilai
collect(Collectors...)akhirmengumpulkan ke List, Set, Map, dll

Operasi perantara bersifat malas (lazy): tidak ada yang dijalankan sampai ada operasi akhir.

Contoh lebih nyata

record Produk(String nama, double harga, String kategori) { }

List<Produk> daftar = List.of(
    new Produk("Pensil", 3000, "alat"),
    new Produk("Buku", 15000, "alat"),
    new Produk("Roti", 8000, "makanan"));

double totalAlat = daftar.stream()
        .filter(p -> p.kategori().equals("alat"))
        .mapToDouble(Produk::harga)
        .sum();                                         // 18000.0

Map<String, List<Produk>> perKategori = daftar.stream()
        .collect(Collectors.groupingBy(Produk::kategori));

String nama = daftar.stream().map(Produk::nama).collect(Collectors.joining(", "));

Optional

Optional<T> membungkus nilai yang mungkin tidak ada, sebagai pengganti null yang rawan NullPointerException.

Optional<Produk> termurah = daftar.stream().min(Comparator.comparingDouble(Produk::harga));
termurah.ifPresent(p -> System.out.println(p.nama()));
String hasil = termurah.map(Produk::nama).orElse("kosong");

Catatan penting

  • Stream hanya bisa dipakai sekali.
  • Variabel lokal yang dipakai di dalam lambda harus effectively final (tidak diubah setelah diisi).
  • Untuk loop sederhana, for biasa kadang lebih jelas; pakai Stream saat memperjelas niat (saring → ubah → kumpulkan).

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X