map () dan flatMap ()
map()
Hanya membutuhkan sebuah Fungsi lambda param di mana T adalah elemen dan R elemen kembali dibangun menggunakan T. Pada akhirnya kita akan memiliki Stream dengan objek Tipe R. Contoh sederhana dapat:
Stream
.of(1,2,3,4,5)
.map(myInt -> "preFix_"+myInt)
.forEach(System.out::println);
Ini hanya membutuhkan elemen 1 hingga 5 dari Tipe Integer
, menggunakan setiap elemen untuk membangun elemen baru dari tipe String
dengan nilai "prefix_"+integer_value
dan mencetaknya.
flatMap()
Sangat berguna untuk mengetahui bahwa flatMap () mengambil fungsi di F<T, R>
mana
T adalah jenis dari mana Stream dapat dibangun dari / dengan . Ini bisa berupa Daftar (T.stream ()), array (Arrays.stream (someArray)), dll. Apa pun yang darinya Aliran dapat dengan / atau bentuk. dalam contoh di bawah ini setiap dev memiliki banyak bahasa, jadi dev. Bahasa adalah Daftar dan akan menggunakan parameter lambda.
R adalah Aliran yang dihasilkan yang akan dibangun menggunakan T. Mengetahui bahwa kita memiliki banyak contoh T, kita secara alami akan memiliki banyak Aliran dari R. Semua Aliran ini dari Tipe R sekarang akan digabungkan menjadi satu Aliran 'flat' tunggal dari Tipe R .
Contoh
Contoh-contoh Bachiri Taoufiq lihat jawabannya di sini sederhana dan mudah dimengerti. Hanya untuk kejelasan, katakan saja kami memiliki tim pengembang:
dev_team = {dev_1,dev_2,dev_3}
, dengan setiap pengembang mengetahui banyak bahasa:
dev_1 = {lang_a,lang_b,lang_c},
dev_2 = {lang_d},
dev_2 = {lang_e,lang_f}
Menerapkan Stream.map () di dev_team untuk mendapatkan bahasa dari masing-masing dev:
dev_team.map(dev -> dev.getLanguages())
akan memberi Anda struktur ini:
{
{lang_a,lang_b,lang_c},
{lang_d},
{lang_e,lang_f}
}
yang pada dasarnya adalah a List<List<Languages>> /Object[Languages[]]
. Tidak terlalu cantik, tidak seperti Java8 !!
dengan Stream.flatMap()
Anda dapat 'meratakan' hal-hal karena mengambil struktur di atas
dan mengubahnya menjadi {lang_a, lang_b, lang_c, lang_d, lang_e, lang_f}
, yang pada dasarnya dapat digunakan sebagai List<Languages>/Language[]/etc
...
jadi pada akhirnya, kode Anda akan lebih masuk akal seperti ini:
dev_team
.stream() /* {dev_1,dev_2,dev_3} */
.map(dev -> dev.getLanguages()) /* {{lang_a,...,lang_c},{lang_d}{lang_e,lang_f}}} */
.flatMap(languages -> languages.stream()) /* {lang_a,...,lang_d, lang_e, lang_f} */
.doWhateverWithYourNewStreamHere();
atau hanya:
dev_team
.stream() /* {dev_1,dev_2,dev_3} */
.flatMap(dev -> dev.getLanguages().stream()) /* {lang_a,...,lang_d, lang_e, lang_f} */
.doWhateverWithYourNewStreamHere();
Kapan menggunakan peta () dan menggunakan flatMap () :
Gunakan map()
ketika setiap elemen tipe T dari aliran Anda seharusnya dipetakan / diubah menjadi elemen tunggal tipe R. Hasilnya adalah pemetaan tipe (1 elemen awal -> 1 elemen ujung) dan aliran baru elemen tipe R dikembalikan.
Gunakan flatMap()
ketika setiap elemen tipe T dari aliran Anda seharusnya dipetakan / diubah menjadi Koleksi elemen tipe R. Hasilnya adalah pemetaan tipe (1 elemen awal -> n elemen ujung) . Koleksi ini kemudian digabung (atau diratakan ) ke aliran baru elemen tipe R. Ini berguna misalnya untuk mewakili loop bersarang .
Pra Jawa 8:
List<Foo> myFoos = new ArrayList<Foo>();
for(Foo foo: myFoos){
for(Bar bar: foo.getMyBars()){
System.out.println(bar.getMyName());
}
}
Pos Jawa 8
myFoos
.stream()
.flatMap(foo -> foo.getMyBars().stream())
.forEach(bar -> System.out.println(bar.getMyName()));
map :: Stream T -> (T -> R) -> Stream R
,flatMap :: Stream T -> (T -> Stream R) -> Stream R
.