1. Pengenalan
Dalam tutorial ini, kita akan membincangkan beberapa contoh bagaimana untuk menggunakan Java Stream suntuk bekerjasama dengan Peta s. Perlu diingat bahawa beberapa latihan ini dapat diselesaikan dengan menggunakan struktur data Peta dua arah , tetapi kami berminat di sini dalam pendekatan fungsional.
Pertama, kami menerangkan idea asas yang akan kami gunakan untuk bekerjasama dengan Peta dan Strim . Kemudian kami membentangkan beberapa masalah yang berbeza berkaitan dengan Peta dan penyelesaian konkritnya menggunakan Stream s.
2. Idea Asas
Perkara utama yang perlu diperhatikan ialah Stream adalah urutan elemen yang dapat diperoleh dengan mudah dari Koleksi .
Peta mempunyai struktur yang berbeza, dengan pemetaan dari kunci ke nilai, tanpa urutan. Ini tidak bermaksud bahawa kita tidak dapat mengubah struktur Peta menjadi urutan yang berbeza yang kemudian memungkinkan kita bekerja dengan cara semula jadi dengan Stream API.
Mari kita lihat cara mendapatkan Koleksi yang berbeza dari Peta , yang kemudian kita dapat berpusing ke dalam Aliran :
Map someMap = new HashMap();
Kami dapat memperoleh satu set pasangan nilai-kunci:
Set
entries = someMap.entrySet();
Kita juga boleh mendapatkan kunci yang berkaitan dengan Peta :
Set keySet = someMap.keySet();
Atau kita boleh bekerja secara langsung dengan set nilai:
Collection values = someMap.values();
Ini masing-masing memberi kita jalan masuk untuk memproses koleksi tersebut dengan mendapatkan aliran dari mereka:
Stream
entriesStream = entries.stream(); Stream valuesStream = values.stream(); Stream keysStream = keySet.stream();
3. Mendapatkan Peta 's Keys Menggunakan Stream s
3.1. Data Input
Anggaplah kita mempunyai Peta :
Map books = new HashMap(); books.put( "978-0201633610", "Design patterns : elements of reusable object-oriented software"); books.put( "978-1617291999", "Java 8 in Action: Lambdas, Streams, and functional-style programming"); books.put("978-0134685991", "Effective Java");
Kami berminat untuk mencari ISBN untuk buku dengan judul "Java Berkesan".
3.2. Mendapatkan Pertandingan
Oleh kerana judul buku tidak ada di Peta kami , kami ingin menunjukkan bahawa tidak ada ISBN yang berkaitan dengannya. Kita boleh menggunakan Pilihan untuk menyatakan bahawa :
Mari kita anggap untuk contoh ini bahawa kita berminat dengan sebarang kunci untuk buku yang sesuai dengan tajuk itu:
Optional optionalIsbn = books.entrySet().stream() .filter(e -> "Effective Java".equals(e.getValue())) .map(Map.Entry::getKey) .findFirst(); assertEquals("978-0134685991", optionalIsbn.get());
Mari kita analisis kodnya. Pertama, kita memperoleh entri Set dari Peta , seperti yang kita lihat sebelumnya.
Kami hanya ingin menganggap entri dengan "Java Berkesan" sebagai judul, jadi operasi perantaraan pertama akan menjadi penapis.
Kami tidak berminat dengan keseluruhan entri Peta , tetapi pada kunci setiap entri. Oleh itu, operasi perantaraan yang dirantai seterusnya melakukan itu: ia adalah operasi peta yang akan menghasilkan aliran baru sebagai output yang hanya akan mengandungi kunci untuk entri yang sesuai dengan tajuk yang kita cari.
Oleh kerana kami hanya mahukan satu hasil, kami dapat menerapkan operasi terminal findFirst () , yang akan memberikan nilai awal dalam Aliran sebagai objek Pilihan .
Mari lihat kes di mana tajuk tidak wujud:
Optional optionalIsbn = books.entrySet().stream() .filter(e -> "Non Existent Title".equals(e.getValue())) .map(Map.Entry::getKey).findFirst(); assertEquals(false, optionalIsbn.isPresent());
3.3. Mengambil Keputusan Pelbagai
Mari ubah masalahnya sekarang untuk melihat bagaimana kita dapat menangani pengembalian hasil dan bukannya satu.
Untuk memperoleh banyak hasil, mari tambahkan buku berikut ke Peta kami :
books.put("978-0321356680", "Effective Java: Second Edition");
Jadi sekarang, jika kita mencari semua buku yang dimulai dengan "Java Berkesan", kita akan mendapat lebih dari satu hasil:
List isbnCodes = books.entrySet().stream() .filter(e -> e.getValue().startsWith("Effective Java")) .map(Map.Entry::getKey) .collect(Collectors.toList()); assertTrue(isbnCodes.contains("978-0321356680")); assertTrue(isbnCodes.contains("978-0134685991"));
Apa yang telah kami lakukan dalam hal ini adalah mengganti kondisi filter untuk memastikan apakah nilai dalam Peta dimulai dengan "Java Efektif" dan bukannya membandingkan kesetaraan String .
Kali ini, kami mengumpulkan keputusan - bukannya memilih yang pertama - memasukkan perlawanan ke dalam Senarai .
4. Mendapatkan Peta Nilai 's Menggunakan Stream s
Sekarang, mari kita fokus pada masalah yang berbeza dengan peta: Daripada mendapatkan ISBN berdasarkan tajuk , kami akan mencuba dan mendapatkan tajuk berdasarkan ISBN.
Mari gunakan Peta asal . Kami ingin mencari tajuk yang ISBNnya bermula dengan "978-0".
List titles = books.entrySet().stream() .filter(e -> e.getKey().startsWith("978-0")) .map(Map.Entry::getValue) .collect(Collectors.toList()); assertEquals(2, titles.size()); assertTrue(titles.contains( "Design patterns : elements of reusable object-oriented software")); assertTrue(titles.contains("Effective Java"));
Penyelesaian ini serupa dengan penyelesaian untuk sekumpulan masalah kami sebelumnya - kami mengalirkan set entri, kemudian menapis, memetakan, dan mengumpulkan.
Dan seperti sebelumnya, jika kita hanya ingin mengembalikan pertandingan pertama, kita dapat setelah kaedah peta memanggil kaedah findFirst () dan bukannya mengumpulkan semua hasil dalam Daftar .
5. Kesimpulan
Kami telah menunjukkan cara memproses Peta dengan cara yang berfungsi .
Secara khusus, kita telah melihat bahawa setelah kita beralih menggunakan koleksi yang berkaitan dengan Peta , pemprosesan menggunakan Stream menjadi lebih mudah dan intuitif.
Dan, tentu saja, semua contoh boleh didapati dalam projek GitHub.