Reduksi normal dimaksudkan untuk menggabungkan dua nilai yang tidak berubah seperti int, dobel, dll. Dan menghasilkan yang baru; ini adalah pengurangan yang tidak berubah . Sebaliknya, metode kumpulkan dirancang untuk bermutasi wadah untuk mengakumulasikan hasil yang seharusnya dihasilkan.
Untuk mengilustrasikan masalah, misalkan Anda ingin mencapai Collectors.toList()
menggunakan pengurangan sederhana seperti
List<Integer> numbers = stream.reduce(
new ArrayList<Integer>(),
(List<Integer> l, Integer e) -> {
l.add(e);
return l;
},
(List<Integer> l1, List<Integer> l2) -> {
l1.addAll(l2);
return l1;
});
Ini setara dengan Collectors.toList()
. Namun, dalam hal ini Anda memutasikan List<Integer>
. Seperti yang kita ketahui, ArrayList
ini bukan thread-safe, juga tidak aman untuk menambah / menghapus nilai dari itu saat iterasi sehingga Anda akan mendapatkan pengecualian bersamaan atau ArrayIndexOutOfBoundsException
atau segala jenis pengecualian (terutama ketika dijalankan secara paralel) ketika Anda memperbarui daftar atau penggabung mencoba untuk menggabungkan daftar karena Anda mengubah daftar dengan mengakumulasi (menambahkan) bilangan bulat ke dalamnya. Jika Anda ingin membuat utas ini aman, Anda harus memberikan daftar baru setiap kali yang akan mengganggu kinerja.
Sebaliknya, Collectors.toList()
karya - karyanya serupa. Namun, itu menjamin keamanan utas saat Anda mengakumulasi nilai-nilai ke dalam daftar. Dari dokumentasi untuk collect
metode ini :
Melakukan operasi pengurangan yang bisa berubah pada elemen aliran ini menggunakan Kolektor. Jika aliran paralel, dan Kolektor bersamaan, dan aliran tidak berurutan atau kolektor tidak berurutan, maka pengurangan bersamaan akan dilakukan. Ketika dieksekusi secara paralel, beberapa hasil antara dapat dipakai, diisi, dan digabungkan untuk menjaga isolasi struktur data yang bisa berubah. Oleh karena itu, bahkan ketika dieksekusi secara paralel dengan struktur data yang tidak aman (seperti ArrayList), tidak diperlukan sinkronisasi tambahan untuk pengurangan paralel.
Jadi, untuk menjawab pertanyaanmu:
Kapan Anda akan menggunakan collect()
vs reduce()
?
jika Anda memiliki nilai-nilai abadi seperti ints
, doubles
, Strings
maka pengurangan biasa bekerja dengan baik. Namun, jika Anda harus reduce
nilai-nilai Anda ke katakanlah List
(struktur data bisa berubah) maka Anda perlu menggunakan pengurangan bisa berubah dengan collect
metode ini.