Bekerja Dengan Peta Menggunakan Aliran

1. Perkenalan

Dalam tutorial ini, kita akan membahas beberapa contoh bagaimana menggunakan Java Streaming suntuk bekerja dengan Map s. Perlu dicatat bahwa beberapa dari latihan ini dapat diselesaikan menggunakan struktur data Peta dua arah , tetapi kami tertarik di sini dalam pendekatan fungsional.

Pertama, kami menjelaskan ide dasar yang akan kami gunakan untuk bekerja dengan Maps dan Stream . Kemudian kami menyajikan beberapa masalah berbeda yang terkait dengan Maps dan solusi konkretnya menggunakan Stream s.

2. Ide Dasar

Hal utama yang harus diperhatikan adalah Stream adalah urutan elemen yang dapat diperoleh dengan mudah dari Koleksi .

Peta memiliki struktur yang berbeda, dengan pemetaan dari kunci ke nilai, tanpa urutan. Ini tidak berarti bahwa kami tidak dapat mengubah struktur Peta menjadi urutan berbeda yang kemudian memungkinkan kami untuk bekerja secara alami dengan API Stream.

Mari kita lihat cara mendapatkan Koleksi yang berbeda dari Peta , yang kemudian dapat kita putar menjadi Aliran :

Map someMap = new HashMap();

Kita bisa mendapatkan satu set pasangan nilai kunci:

Set
    
      entries = someMap.entrySet();
    

Kita juga bisa mendapatkan set kunci yang terkait dengan Peta :

Set keySet = someMap.keySet();

Atau kita bisa bekerja langsung dengan kumpulan nilai:

Collection values = someMap.values();

Ini masing-masing memberi kita titik 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 Streaming s

3.1. Memasukan data

Mari kita asumsikan kita memiliki 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 tertarik untuk menemukan ISBN untuk buku berjudul “Java Efektif”.

3.2. Mengambil Pertandingan

Karena judul buku tidak mungkin ada di Peta kami , kami ingin menunjukkan bahwa tidak ada ISBN terkait untuk itu. Kita dapat menggunakan Opsional untuk menyatakan bahwa :

Mari kita asumsikan untuk contoh ini bahwa kita tertarik pada kunci apa pun untuk buku yang cocok dengan judul 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 kodenya. Pertama, kita mendapatkan entrySet dari Peta , seperti yang kita lihat sebelumnya.

Kami hanya ingin mempertimbangkan entri dengan judul "Java Efektif", jadi operasi perantara pertama akan menjadi filter.

Kami tidak tertarik pada keseluruhan entri Peta , tetapi pada kunci setiap entri. Jadi, operasi perantara berantai berikutnya melakukan hal itu: ini adalah operasi peta yang akan menghasilkan aliran baru sebagai keluaran yang hanya akan berisi kunci untuk entri yang cocok dengan judul yang kita cari.

Karena kita hanya menginginkan satu hasil, kita bisa menerapkan operasi terminal findFirst () , yang akan memberikan nilai awal di Stream sebagai objek Opsional .

Mari kita lihat kasus di mana judul tidak ada:

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 Banyak Hasil

Mari kita ubah masalahnya sekarang untuk melihat bagaimana kita bisa menangani mengembalikan banyak hasil alih-alih satu.

Untuk mendapatkan beberapa hasil kembali, mari tambahkan buku berikut ke Peta kita :

books.put("978-0321356680", "Effective Java: Second Edition"); 

Jadi sekarang, jika kita mencari semua buku yang dimulai dengan "Java Efektif", kita akan mendapatkan 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 kita lakukan dalam kasus ini adalah mengganti kondisi filter untuk memverifikasi apakah nilai dalam Peta dimulai dengan "Java Efektif" daripada membandingkan persamaan String .

Kali ini, kami mengumpulkan hasilnya - alih-alih memilih yang pertama - memasukkan pertandingan ke dalam Daftar .

4. Mendapatkan Peta Nilai 's Menggunakan Streaming s

Sekarang, mari kita fokus pada masalah yang berbeda dengan peta: Alih-alih mendapatkan ISBN berdasarkan judul , kita akan mencoba dan mendapatkan judul berdasarkan ISBN.

Mari gunakan Peta asli . Kami ingin mencari judul yang ISBN-nya diawali 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"));

Solusi ini mirip dengan solusi untuk rangkaian masalah kami sebelumnya - kami mengalirkan kumpulan entri, lalu memfilter, memetakan, dan mengumpulkan.

Dan seperti sebelumnya, jika kita ingin kembali hanya pertandingan pertama, kita bisa setelah peta metode memanggil FindFirst () metode bukan mengumpulkan semua hasil dalam Daftar .

5. Kesimpulan

Kami telah menunjukkan bagaimana memproses Peta secara fungsional .

Secara khusus, kami telah melihat bahwa setelah kami beralih menggunakan koleksi terkait ke Peta , pemrosesan menggunakan Stream menjadi lebih mudah dan intuitif.

Dan, tentu saja, semua contoh dapat ditemukan di proyek GitHub.