Panduan API Koleksi Vavr

VAVR (sebelumnya dikenal sebagai Javaslang) adalah perpustakaan fungsional nirlaba untuk Java 8+. Ini memungkinkan Anda untuk menulis kode mirip Scala fungsional di Jawa dan berfungsi untuk mengurangi jumlah kode dan meningkatkan kualitasnya. Situs perpustakaan .

Di bawah potongan adalah terjemahan dari artikel yang mensistematisasikan informasi pada Vavr Collections API .

Diterjemahkan oleh @middle_java

Artikel Asli Yang Dimodifikasi Terakhir: 15 Agustus 2019

1. Ikhtisar


Perpustakaan Vavr, sebelumnya dikenal sebagai Javaslang, adalah perpustakaan fungsional untuk Jawa. Pada artikel ini, kami mengeksplorasi API koleksi yang kuat.

Lihat artikel ini untuk informasi lebih lanjut tentang perpustakaan ini.

2. Koleksi Persisten


Koleksi persisten, saat dimodifikasi, membuat versi baru koleksi tanpa mengubah versi saat ini.

Dukungan untuk beberapa versi dari koleksi yang sama dapat menyebabkan penggunaan CPU dan memori yang tidak efisien. Namun, perpustakaan koleksi Vavr mengatasi ini dengan berbagi struktur data antara versi koleksi yang berbeda.

Ini pada dasarnya berbeda dari unmodifiableCollection() dari Collections kelas utilitas Java, yang hanya menyediakan pembungkus untuk koleksi basis.

Mencoba mengubah koleksi seperti itu UnsupportedOperationException alih-alih membuat versi baru. Selain itu, koleksi basis masih bisa berubah melalui tautan langsung ke sana.

3. Dapat dilewati


Traversable adalah tipe dasar dari semua koleksi VAVR. Antarmuka ini mendefinisikan metode umum untuk semua struktur data.

Ini memberikan beberapa metode default yang berguna, seperti size() , get() , filter() , isEmpty() dan lainnya yang diwarisi oleh sub-interface.

Kami lebih jauh menjelajahi perpustakaan koleksi.

4. Seq


Mari kita mulai dengan urutannya.

Antarmuka Seq adalah struktur data berurutan. Ini adalah antarmuka induk untuk List , Stream , Queue , Array , Vector dan CharSeq . Semua struktur data ini memiliki sifat uniknya sendiri, yang akan kita bahas di bawah ini.

4.1. Daftar


List adalah operasi yang dihitung dengan penuh semangat (dievaluasi dengan penuh semangat, dilakukan segera setelah nilai LinearSeq diketahui) urutan elemen yang memperluas antarmuka LinearSeq .

List Persistent dibangun secara rekursif menggunakan kepala dan ekor :

  • Kepala adalah elemen pertama
  • Ekor - daftar yang mengandung elemen yang tersisa (daftar ini juga dibentuk dari kepala dan ekor)

List API berisi metode pabrik statis yang dapat Anda gunakan untuk membuat List . Anda dapat menggunakan metode statis of() untuk membuat instance List dari satu atau lebih objek.

Anda juga dapat menggunakan metode static empty() untuk membuat List kosong dan metode ofAll() untuk membuat List tipe Iterable :

 List < String > list = List.of( "Java", "PHP", "Jquery", "JavaScript", "JShell", "JAVA"); 

Mari kita lihat beberapa contoh manipulasi daftar.

Kita dapat menggunakan metode drop() dan variannya untuk menghapus elemen N pertama:

 List list1 = list.drop(2); assertFalse(list1.contains("Java") && list1.contains("PHP")); List list2 = list.dropRight(2); assertFalse(list2.contains("JAVA") && list2.contains("JShell")); List list3 = list.dropUntil(s - > s.contains("Shell")); assertEquals(list3.size(), 2); List list4 = list.dropWhile(s - > s.length() > 0); assertTrue(list4.isEmpty()); 

drop(int n) menghapus n item dari daftar, mulai dari item pertama, sementara dropRight() melakukan hal yang sama, mulai dari item terakhir dalam daftar.

dropUntil() menghapus item dari daftar sampai predikat true , sementara dropWhile() menghapus item sampai predikat true .

Ada juga dropRightWhile() dan dropRightUntil() yang menghapus item mulai dari kanan.

Selanjutnya, take(int n) digunakan untuk mengambil item dari daftar. Dibutuhkan n item dari daftar dan kemudian berhenti. Ada juga takeRight(int n) , yang mengambil elemen dari akhir daftar:

 List list5 = list.take(1); assertEquals(list5.single(), "Java"); List list6 = list.takeRight(1); assertEquals(list5.single(), "Java"); List list7 = list.takeUntil(s - > s.length() > 6); assertEquals(list3.size(), 3); 

Akhirnya, takeUntil() mengambil elemen dari daftar sampai predikat menjadi true . Ada varian takeWhile() yang juga menggunakan argumen predikat.

Selain itu, API memiliki metode lain yang bermanfaat, misalnya, bahkan distinct() , yang mengembalikan daftar elemen dengan duplikat yang dihapus, dan distinctBy() , yang menerima Comparator untuk menentukan kesetaraan.

Sangat menarik bahwa ada juga intersperse() , yang menyisipkan elemen di antara setiap elemen daftar. Ini bisa sangat nyaman untuk operasi dengan String :

 List list8 = list .distinctBy((s1, s2) - > s1.startsWith(s2.charAt(0) + "") ? 0 : 1); assertEquals(list3.size(), 2); String words = List.of("Boys", "Girls") .intersperse("and") .reduce((s1, s2) - > s1.concat(" " + s2)) .trim(); assertEquals(words, "Boys and Girls"); 

Ingin membagi daftar menjadi beberapa kategori? Dan untuk ini ada API:

 Iterator < List < String >> iterator = list.grouped(2); assertEquals(iterator.head().size(), 2); Map < Boolean, List < String >> map = list.groupBy(e - > e.startsWith("J")); assertEquals(map.size(), 2); assertEquals(map.get(false).get().size(), 1); assertEquals(map.get(true).get().size(), 5); 

Metode group(int n) membagi List menjadi kelompok-kelompok elemen n masing-masing. Metode groupdBy() mengambil Function yang berisi logika untuk memisahkan daftar dan mengembalikan Map dengan dua elemen: true dan false .

Kunci sebenarnya dipetakan ke List elemen yang memenuhi kondisi yang ditentukan dalam Function . Kunci false memetakan ke List elemen yang tidak memenuhi kondisi ini.

Seperti yang diharapkan, ketika mengubah List , List asli tidak benar-benar berubah. Sebaliknya, versi baru List selalu dikembalikan.

Kita juga dapat berinteraksi dengan List menggunakan semantik stack - mengekstraksi elemen sesuai dengan prinsip "last in, first out" (LIFO). Dalam pengertian ini, metode API seperti peek() , pop() dan push() ada untuk memanipulasi tumpukan:

 List < Integer > intList = List.empty(); List < Integer > intList1 = intList.pushAll(List.rangeClosed(5, 10)); assertEquals(intList1.peek(), Integer.valueOf(10)); List intList2 = intList1.pop(); assertEquals(intList2.size(), (intList1.size() - 1)); 

Fungsi pushAll() digunakan untuk memasukkan berbagai bilangan bulat pada stack, dan fungsi peek() digunakan untuk mengambil elemen head stack. Ada juga metode peekOption() yang dapat membungkus hasilnya dalam objek Option .

Ada metode lain yang menarik dan sangat berguna dalam antarmuka List yang didokumentasikan secara menyeluruh dalam dokumen Java .

4.2. Antrian


Queue tidak berubah menyimpan elemen, memungkinkan Anda untuk mengambilnya sesuai dengan prinsip FIFO (masuk pertama, keluar pertama).

Queue dalam Queue terdiri dari dua daftar tertaut: List depan dan List belakang. List depan berisi item yang dihapus dari antrian, dan List belakang berisi item yang antri.

Ini memungkinkan Anda untuk menempatkan operasi antrian dan menghapus dari antrian ke kompleksitas O (1) . Ketika List berakhir di List depan ketika dihapus dari antrian, List belakang terbalik dan menjadi List depan baru.

Mari kita membuat antrian:

 Queue < Integer > queue = Queue.of(1, 2); Queue < Integer > secondQueue = queue.enqueueAll(List.of(4, 5)); assertEquals(3, queue.size()); assertEquals(5, secondQueue.size()); Tuple2 < Integer, Queue < Integer >> result = secondQueue.dequeue(); assertEquals(Integer.valueOf(1), result._1); Queue < Integer > tailQueue = result._2; assertFalse(tailQueue.contains(secondQueue.get(0))); 

Fungsi dequeue() menghilangkan elemen head dari Queue dan mengembalikan Tuple2<T, Q> . Elemen pertama dari tuple adalah elemen head yang dihapus dari antrian, elemen kedua dari tuple adalah elemen Queue tersisa.

Kita bisa menggunakan combination(n) untuk mendapatkan semua kemungkinan kombinasi N elemen dalam Queue :

 Queue < Queue < Integer >> queue1 = queue.combinations(2); assertEquals(queue1.get(2).toCharSeq(), CharSeq.of("23")); 

Sekali lagi, Queue asli tidak berubah saat menambah / menghapus item dari antrian.

4.3. Aliran


Stream adalah implementasi dari daftar yang ditautkan secara malas yang sangat berbeda dari java.util.stream . Tidak seperti java.util.stream , Stream Vavr menyimpan data dan dengan malas menghitung elemen berikutnya.
Katakanlah kita memiliki bilangan bulat Stream :

 Stream < Integer > s = Stream.of(2, 1, 3, 4); 

Saat mencetak hasil s.toString() di konsol, hanya Stream (2 ,?) yang akan ditampilkan. Ini berarti bahwa hanya elemen Head Stream yang dihitung, sedangkan elemen ekor tidak.

Memanggil s.get(3) dan kemudian menampilkan hasil s.tail() mengembalikan Stream (1, 3, 4 ,?) . Sebaliknya, jika Anda tidak memanggil s.get(3) - yang akan membuat Stream menghitung elemen terakhir - hanya Stream (1 ,?) Akan menjadi hasil dari s.tail() ) . Ini berarti bahwa hanya elemen ekor pertama yang dihitung.

Perilaku ini dapat meningkatkan kinerja dan memungkinkan Stream untuk digunakan untuk mewakili urutan yang (secara teoritis) sangat panjang.
Stream di Vavr tidak dapat diubah dan dapat berupa Empty atau Cons . Cons terdiri dari elemen kepala dan ekor Stream dihitung malas. Tidak seperti List , Stream menyimpan elemen kepala dalam memori. Elemen ekor dihitung sesuai kebutuhan.

Mari kita buat Stream 10 bilangan bulat positif dan hitung jumlah bilangan genap:

 Stream < Integer > intStream = Stream.iterate(0, i - > i + 1) .take(10); assertEquals(10, intStream.size()); long evenSum = intStream.filter(i - > i % 2 == 0) .sum() .longValue(); assertEquals(20, evenSum); 

Berbeda dengan Stream API dari Java 8, Stream di Vavr adalah struktur data untuk menyimpan urutan elemen.

Oleh karena itu, ia memiliki metode seperti get() , append() , insert() dan lainnya untuk memanipulasi elemen-elemennya. drop() , distinct() dan beberapa metode lain yang dibahas sebelumnya juga tersedia.

Akhirnya, mari kita cepat tunjukkan tabulate() di Stream . Metode ini mengembalikan Stream panjang n mengandung elemen yang merupakan hasil dari penerapan fungsi:

 Stream < Integer > s1 = Stream.tabulate(5, (i) - > i + 1); assertEquals(s1.get(2).intValue(), 3); 

Kita juga dapat menggunakan zip() untuk membuat Stream dari Tuple2<Integer, Integer> , yang berisi elemen yang dibentuk dengan menggabungkan dua Stream :

 Stream < Integer > s = Stream.of(2, 1, 3, 4); Stream < Tuple2 < Integer, Integer >> s2 = s.zip(List.of(7, 8, 9)); Tuple2 < Integer, Integer > t1 = s2.get(0); assertEquals(t1._1().intValue(), 2); assertEquals(t1._2().intValue(), 7); 

4.4. Array


Array adalah urutan indeks yang tidak berubah yang menyediakan akses acak yang efisien. Ini didasarkan pada array Java objek. Intinya, ini adalah pembungkus Traversable untuk berbagai objek bertipe T

Anda dapat membuat turunan Array menggunakan metode statis of() . Selain itu, Anda dapat membuat berbagai elemen menggunakan range() metode statis range() dan rangeBy() . Metode rangeBy() memiliki parameter ketiga, yang memungkinkan Anda menentukan langkah.

Metode range() dan rangeBy() akan membuat elemen, mulai dari nilai awal ke nilai akhir dikurangi satu. Jika kita perlu memasukkan nilai akhir, kita dapat menggunakan rangeClosed() atau rangeClosedBy() :

 Array < Integer > rArray = Array.range(1, 5); assertFalse(rArray.contains(5)); Array < Integer > rArray2 = Array.rangeClosed(1, 5); assertTrue(rArray2.contains(5)); Array < Integer > rArray3 = Array.rangeClosedBy(1, 6, 2); assertEquals(list3.size(), 3); 

Mari kita bekerja dengan elemen menggunakan indeks:

 Array < Integer > intArray = Array.of(1, 2, 3); Array < Integer > newArray = intArray.removeAt(1); assertEquals(3, intArray.size()); assertEquals(2, newArray.size()); assertEquals(3, newArray.get(1).intValue()); Array < Integer > array2 = intArray.replace(1, 5); assertEquals(s1.get(0).intValue(), 5); 

4.5. Vektor


Vector adalah persilangan antara Array dan List , menyediakan urutan elemen yang diindeks, memungkinkan akses acak dan modifikasi dalam waktu konstan:

 Vector < Integer > intVector = Vector.range(1, 5); Vector < Integer > newVector = intVector.replace(2, 6); assertEquals(4, intVector.size()); assertEquals(4, newVector.size()); assertEquals(2, intVector.get(1).intValue()); assertEquals(6, newVector.get(1).intValue()); 

4.6. Charseq


CharSeq adalah objek koleksi untuk mewakili urutan karakter primitif. Intinya, ini adalah pembungkus untuk String dengan penambahan operasi pengumpulan.

Untuk membuat CharSeq Anda harus melakukan yang berikut ini.

 CharSeq chars = CharSeq.of("vavr"); CharSeq newChars = chars.replace('v', 'V'); assertEquals(4, chars.size()); assertEquals(4, newChars.size()); assertEquals('v', chars.charAt(0)); assertEquals('V', newChars.charAt(0)); assertEquals("Vavr", newChars.mkString()); 

5. Atur


Bagian ini membahas berbagai implementasi Set di perpustakaan koleksi. Fitur unik dari struktur data Set adalah tidak mengijinkan nilai duplikat.

Ada berbagai implementasi Set . Yang utama adalah HashSet . TreeSet tidak memungkinkan elemen duplikat dan dapat diurutkan. LinkedHashSet mempertahankan urutan elemen penyisipan.

Mari kita lihat lebih dekat implementasi ini satu demi satu.

5.1. Hashset


HashSet memiliki metode pabrik statis untuk membuat instance baru. Beberapa di antaranya kami pelajari sebelumnya dalam artikel ini, misalnya of() , ofAll() dan variasi pada range() metode.

Perbedaan antara dua set dapat diperoleh dengan menggunakan metode diff() . Juga, metode union() dan intersect() mengembalikan union dan persimpangan dua set :

 HashSet < Integer > set0 = HashSet.rangeClosed(1, 5); HashSet < Integer > set0 = HashSet.rangeClosed(1, 5); assertEquals(set0.union(set1), HashSet.rangeClosed(1, 6)); assertEquals(set0.diff(set1), HashSet.rangeClosed(1, 2)); assertEquals(set0.intersect(set1), HashSet.rangeClosed(3, 5)); 

Kami juga dapat melakukan operasi dasar, seperti menambah dan menghapus elemen:

 HashSet < String > set = HashSet.of("Red", "Green", "Blue"); HashSet < String > newSet = set.add("Yellow"); assertEquals(3, set.size()); assertEquals(4, newSet.size()); assertTrue(newSet.contains("Yellow")); 

Implementasi HashSet didasarkan pada hash array mapped trie (HAMT) , yang menawarkan kinerja yang unggul dibandingkan dengan HashTable biasa dan strukturnya membuatnya cocok untuk mendukung koleksi persisten.

5.2. Treeset


Immutable TreeSet adalah implementasi dari antarmuka SortedSet . Ini menyimpan satu set elemen yang diurutkan dan diimplementasikan menggunakan pohon pencarian biner. Semua operasinya dilakukan selama waktu O (log n) .

Secara default, elemen TreeSet diurutkan dalam urutan alami mereka.
Mari kita membuat SortedSet menggunakan urutan sortir alami:

 SortedSet < String > set = TreeSet.of("Red", "Green", "Blue"); assertEquals("Blue", set.head()); SortedSet < Integer > intSet = TreeSet.of(1, 2, 3); assertEquals(2, intSet.average().get().intValue()); 

Untuk mengatur item dengan cara kustom, berikan instance Comparator saat membuat TreeSet . Anda juga dapat membuat string dari serangkaian elemen:

 SortedSet < String > reversedSet = TreeSet.of(Comparator.reverseOrder(), "Green", "Red", "Blue"); assertEquals("Red", reversedSet.head()); String str = reversedSet.mkString(" and "); assertEquals("Red and Green and Blue", str); 

5.3. Bitset


Koleksi VAVR juga memiliki implementasi BitSet tidak berubah. Antarmuka BitSet memperluas antarmuka SortedSet . BitSet dapat dibuat menggunakan metode statis di BitSet.Builder .
Seperti dengan implementasi lain dari struktur Set data, BitSet tidak memungkinkan Anda untuk menambahkan rekaman duplikat ke set.

Ini mewarisi metode untuk manipulasi dari antarmuka Traversable . Perhatikan bahwa ini berbeda dari java.util.BitSet dari perpustakaan Java standar. Data BitSet tidak dapat berisi nilai-nilai String .

Pertimbangkan untuk membuat instance BitSet menggunakan metode of() factory:

 BitSet < Integer > bitSet = BitSet.of(1, 2, 3, 4, 5, 6, 7, 8); BitSet < Integer > bitSet1 = bitSet.takeUntil(i - > i > 4); assertEquals(list3.size(), 4); 

Untuk memilih empat elemen BitSet pertama BitSet kami menggunakan perintah takeUntil() . Operasi mengembalikan contoh baru. Perhatikan bahwa metode takeUntil() didefinisikan dalam antarmuka Traversable , yang merupakan antarmuka induk untuk BitSet .

Metode dan operasi lain yang dijelaskan di atas didefinisikan dalam antarmuka Traversable juga berlaku untuk BitSet .

6. Peta


Map adalah struktur data nilai kunci. Map di Vavr tidak dapat diubah dan memiliki implementasi untuk HashMap , TreeMap dan LinkedHashMap .

Biasanya, kontrak peta tidak memungkinkan kunci duplikat, sementara nilai duplikat dipetakan ke kunci yang berbeda mungkin.

6.1. Hashmap


HashMap adalah implementasi dari antarmuka Map tidak dapat diubah. Ini menyimpan pasangan nilai kunci menggunakan hash kunci.

Map di Vavr menggunakan Tuple2 untuk mewakili pasangan nilai kunci dan bukan tipe Entry tradisional:

 Map < Integer, List < Integer >> map = List.rangeClosed(0, 10) .groupBy(i - > i % 2); assertEquals(2, map.size()); assertEquals(6, map.get(0).get().size()); assertEquals(5, map.get(1).get().size()); 

Seperti HashSet , implementasi HashMap didasarkan pada Hash array mapped trie (HAMT) , yang mengarah ke waktu yang konstan untuk hampir semua operasi.
Elemen peta dapat disaring dengan kunci menggunakan metode filterKeys() atau dengan nilai menggunakan metode filterValues() . Kedua metode menggunakan Predicate sebagai argumen:

 Map < String, String > map1 = HashMap.of("key1", "val1", "key2", "val2", "key3", "val3"); Map < String, String > fMap = map1.filterKeys(k - > k.contains("1") || k.contains("2")); assertFalse(fMap.containsKey("key3")); Map < String, String > map1 = map1.filterValues(v - > v.contains("3")); assertEquals(list3.size(), 1); assertTrue(fMap2.containsValue("val3")); 

Anda juga dapat mengubah elemen peta menggunakan metode map() . Misalnya, mari kita konversi map1 ke Map<String, Integer> :

 Map < String, Integer > map2 = map1.map( (k, v) - > Tuple.of(k, Integer.valueOf(v.charAt(v.length() - 1) + ""))); assertEquals(map2.get("key1").get().intValue(), 1); 

6.2. Treemap


Immutable TreeMap adalah implementasi dari antarmuka SortedMap . Seperti TreeSet , instance kustom Comparator digunakan untuk menyesuaikan pengurutan elemen TreeMap .
SortedMap tunjukkan pembuatan SortedMap :

 SortedMap < Integer, String > map = TreeMap.of(3, "Three", 2, "Two", 4, "Four", 1, "One"); assertEquals(1, map.keySet().toJavaArray()[0]); assertEquals("Four", map.get(4).get()); 

Secara default, entri TreeMap diurutkan dalam urutan kunci alami. Namun, Anda dapat menentukan Comparator akan digunakan untuk menyortir:

 TreeMap < Integer, String > treeMap2 = TreeMap.of(Comparator.reverseOrder(), 3, "three", 6, "six", 1, "one"); assertEquals(treeMap2.keySet().mkString(), "631"); 

Seperti dalam kasus TreeSet , implementasi TreeMap juga dibuat menggunakan pohon, oleh karena itu, operasinya punya waktu O (log n) . Metode map.get(key) mengembalikan Option , yang berisi nilai kunci peta yang ditentukan.

7. Kompatibilitas Java


API Koleksi Vavr sepenuhnya kompatibel dengan Java Collection Framework. Mari kita lihat bagaimana hal ini dilakukan dalam praktek.

7.1. Konversi dari Java ke Vavr


Setiap implementasi pengumpulan di Vavr memiliki pabrik statis metode ofAll() yang menerima java.util.Iterable . Ini memungkinkan Anda untuk membuat koleksi VAVR dari koleksi Java . Demikian pula, metode factory ofAll() langsung menerima Java Stream .

Untuk mengonversi List Java ke List yang tidak dapat diubah:

 java.util.List < Integer > javaList = java.util.Arrays.asList(1, 2, 3, 4); List < Integer > vavrList = List.ofAll(javaList); java.util.stream.Stream < Integer > javaStream = javaList.stream(); Set < Integer > vavrSet = HashSet.ofAll(javaStream); 

Fungsi lain yang berguna adalah collector() , yang dapat digunakan bersama dengan Stream.collect() untuk mendapatkan koleksi Vavr:

 List < Integer > vavrList = IntStream.range(1, 10) .boxed() .filter(i - > i % 2 == 0) .collect(List.collector()); assertEquals(4, vavrList.size()); assertEquals(2, vavrList.head().intValue()); 

7.2. Konversi dari Vavr ke Java


Antarmuka Value memiliki banyak metode untuk mengkonversi dari tipe Vavr ke tipe Java . Metode ini memiliki format toJavaXXX() .

Perhatikan beberapa contoh:

 Integer[] array = List.of(1, 2, 3) .toJavaArray(Integer.class); assertEquals(3, array.length); java.util.Map < String, Integer > map = List.of("1", "2", "3") .toJavaMap(i - > Tuple.of(i, Integer.valueOf(i))); assertEquals(2, map.get("2").intValue()); 

Kami juga dapat menggunakan Java 8 Collectors untuk mengumpulkan item dari koleksi Vavr:

 java.util.Set < Integer > javaSet = List.of(1, 2, 3) .collect(Collectors.toSet()); assertEquals(3, javaSet.size()); assertEquals(1, javaSet.toArray()[0]); 

7.3. Tampilan Koleksi Java


Selain itu, perpustakaan menyediakan apa yang disebut tampilan koleksi yang berfungsi paling baik ketika dikonversi ke koleksi Java. Metode transformasi di bagian sebelumnya iterate over (iterate) semua elemen untuk membuat koleksi Java.

Tampilan, di sisi lain, mengimplementasikan antarmuka Java standar dan mendelegasikan panggilan metode ke koleksi basis Vavr.

Pada saat penulisan ini, hanya tampilan List yang didukung. Setiap kumpulan berurutan memiliki dua metode: satu untuk membuat representasi yang tidak dapat diubah, yang lain untuk bisa berubah.

Metode panggilan untuk mengubah pada tampilan yang tidak berubah UnsupportedOperationException .

Mari kita lihat sebuah contoh:

 @Test(expected = UnsupportedOperationException.class) public void givenVavrList_whenViewConverted_thenException() { java.util.List < Integer > javaList = List.of(1, 2, 3) .asJava(); assertEquals(3, javaList.get(2).intValue()); javaList.add(4); } 

Untuk membuat tampilan yang tidak berubah:

 java.util.List < Integer > javaList = List.of(1, 2, 3) .asJavaMutable(); javaList.add(4); assertEquals(4, javaList.get(3).intValue()); 

8. Kesimpulan


Dalam tutorial ini, kami belajar tentang berbagai struktur data fungsional yang disediakan oleh Vavr Collections API. Ada juga metode API yang bermanfaat dan produktif yang dapat ditemukan di Java doc dan Panduan Pengguna Koleksi Vavr.

Akhirnya, penting untuk dicatat bahwa pustaka juga mendefinisikan Try , Option , Either dan Future , yang memperluas antarmuka Value dan, sebagai hasilnya, mengimplementasikan antarmuka Java Iterable . Ini berarti bahwa dalam beberapa situasi mereka dapat berperilaku seperti koleksi.

Kode sumber lengkap untuk semua contoh dalam artikel ini dapat ditemukan di Github .

Bahan tambahan:
habr.com/en/post/421839
www.baeldung.com/vavr

Diterjemahkan oleh @middle_java

Source: https://habr.com/ru/post/id474402/


All Articles