Java — Stream (Indonesia)
Hari ke 29 mencoba konsisten menulis, hari ini kita akan belajar tentang stream yeah
Java Stream
Stream adalah urutan elemen yang mendukung operasi agregat secara sekuensial maupun paralel, diperkenalkan di Java 8 melalui java.util.stream.
Get Arif Dwi Prasetya’s stories in your inbox
Join Medium for free to get updates from this writer.
Stream bukan struktur data — ia tidak menyimpan data, melainkan memproses data dari sumber (Collection, array, I/O) secara pipeline.
List<String> names = List.of("Alice", "Bob", "Charlie", "Dave");
List<String> result = names.stream() // 1. Source
.filter(n -> n.length() > 3) // 2. Intermediate operation (lazy)
.map(String::toUpperCase) // 2. Intermediate operation (lazy)
.sorted() // 2. Intermediate operation (lazy)
.collect(Collectors.toList()); // 3. Terminal operation (triggers execution)
// Result: [ALICE, CHARLIE, DAVE]Pipeline terdiri dari 3 bagian:
- Source — Collection, array,
Stream.of(), dll - Intermediate operations — lazy, tidak dieksekusi sampai terminal dipanggil
- Terminal operation — memicu eksekusi seluruh pipeline
Fungsi / Keunggulan
1. Kode lebih ringkas dan deklaratif
// Tanpa Stream
List<String> result = new ArrayList<>();
for (String name : names) {
if (name.length() > 3) result.add(name.toUpperCase());
}
// Dengan Stream — lebih ekspresif
List<String> result = names.stream()
.filter(n -> n.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());2. Lazy evaluation — hemat resource
// Hanya memproses sampai elemen pertama ditemukan
Optional<String> first = names.stream()
.filter(n -> n.startsWith("C"))
.findFirst(); // Berhenti setelah menemukan "Charlie"3. Parallel processing mudah
// Cukup ganti .stream() → .parallelStream()
long count = largeList.parallelStream()
.filter(n -> n.length() > 5)
.count();parallelStream() adalah varian Stream yang membagi pekerjaan ke beberapa thread secara otomatis menggunakan Fork/Join Framework dan ForkJoinPool.commonPool().
// stream() — Sequential
Data: [1, 2, 3, 4, 5, 6, 7, 8]
Thread: [Main ──────────────────────►]
1→2→3→4→5→6→7→8
// parallelStream() — Parallel
Data: [1, 2, 3, 4, 5, 6, 7, 8]
Thread-1: [1, 2] ──►
Thread-2: [3, 4] ──► → Gabung → Hasil
Thread-3: [5, 6] ──►
Thread-4: [7, 8] ──►Operasi CPU-intensive (cocok untuk parallel):
List<Integer> bigList = IntStream.rangeClosed(1, 10_000_000)
.boxed()
.collect(Collectors.toList());
// Sequential ~800ms
long count1 = bigList.stream()
.filter(n -> isPrime(n)) // operasi berat
.count();
// Parallel ~200ms (4x lebih cepat di 4-core CPU)
long count2 = bigList.parallelStream()
.filter(n -> isPrime(n))
.count();4. Operasi chaining yang kaya
Map<Integer, List<String>> grouped = names.stream()
.collect(Collectors.groupingBy(String::length));
// {3: ["Bob"], 5: ["Alice", "Dave"], 7: ["Charlie"]}Kapan Digunakan ✅
- Transformasi & filter koleksi — map, filter, reduce
- Data besar dengan
parallelStream()untuk operasi CPU-intensive - Aggregasi — sum, average, grouping, counting
- Functional-style pipeline yang mudah dibaca
- Operasi one-shot pada Collection
// Cocok: agregasi kompleks
double avgSalary = employees.stream()
.filter(e -> e.getDept().equals("Engineering"))
.mapToDouble(Employee::getSalary)
.average()
.orElse(0);Kapan Tidak Digunakan ❌
- Loop sederhana dengan sedikit elemen — pakai
forbiasa saja - Butuh modifikasi index — Stream tidak punya akses index langsung
- Perlu break/continue — tidak bisa di-interrupt (kecuali
findFirst) - Side effects — Stream bukan untuk modifikasi state eksternal
- Performa kritis pada data kecil — overhead Stream lebih besar dari loop
// ❌ Hindari Stream untuk ini — pakai for loop biasa
for (int i = 0; i < list.size(); i++) {
if (kondisiTertentu(i)) break; // Tidak bisa dilakukan di Stream
proses(list.get(i), i); // Butuh index
}Gunakan Stream ketika keterbacaan dan komposabilitas lebih penting dari performa mikro, terutama untuk transformasi data skala menengah ke atas.
Sekian artikel tentang stream ini yg singkat begitu kan, terima kasih
— Arif Dwi Prasetya










