VAVR (früher bekannt als Javaslang) ist eine gemeinnützige Funktionsbibliothek für Java 8+. Es ermöglicht Ihnen das Schreiben von funktionalem Scala-ähnlichem Code in Java und dient dazu, die Codemenge zu reduzieren und die Qualität zu verbessern. 
Bibliotheksseite .
Unter dem Schnitt befindet sich eine Übersetzung eines Artikels, der Informationen zur 
Vavr Collections-API systematisiert.
Übersetzt von 
@middle_javaLetzter geänderter Originalartikel: 15. August 2019
1. Übersicht
Die Vavr-Bibliothek, früher als Javaslang bekannt, ist eine funktionale Bibliothek für Java. In diesem Artikel untersuchen wir die leistungsstarke Sammlungs-API.
Weitere Informationen zu dieser Bibliothek finden Sie in 
diesem Artikel .
2. Persistente Sammlungen
Wenn eine persistente Sammlung geändert wird, wird eine neue Version der Sammlung erstellt, ohne die aktuelle Version zu ändern.
Die Unterstützung mehrerer Versionen derselben Sammlung kann zu einer ineffizienten Nutzung von CPU und Speicher führen. Die Vavr-Sammlungsbibliothek überwindet dies jedoch, indem sie die Datenstruktur zwischen verschiedenen Versionen der Sammlung teilt.
Dies unterscheidet sich grundlegend von 
unmodifiableCollection() von der Java-Dienstprogrammklasse 
Collections , die lediglich einen Wrapper für die Basissammlung bereitstellt.
Beim Versuch, eine solche Sammlung zu ändern, wird 
UnsupportedOperationException anstatt eine neue Version zu erstellen. Darüber hinaus ist die Basissammlung durch eine direkte Verknüpfung weiterhin veränderbar.
3. Durchfahrbar
Traversable ist der Basistyp aller Vavr-Sammlungen. Diese Schnittstelle definiert Methoden, die allen Datenstrukturen gemeinsam sind.
Es bietet einige nützliche Standardmethoden wie 
size() , 
get() , 
filter() , 
isEmpty() und andere, die von 
isEmpty() geerbt werden.
Wir erkunden die Sammlungsbibliothek weiter.
4. Seq
Beginnen wir mit den Sequenzen.
Die 
Seq Schnittstelle ist eine sequentielle Datenstruktur. Dies ist die übergeordnete Schnittstelle für 
List , 
Stream , 
Queue , 
Array , 
Vector und 
CharSeq . Alle diese Datenstrukturen haben ihre eigenen einzigartigen Eigenschaften, die wir unten diskutieren werden.
4.1. Liste
List ist eine energetisch berechnete (eifrig evaluierte Operation, sobald die Werte ihrer Operanden bekannt werden), eine Folge von Elementen, die die 
LinearSeq Schnittstelle erweitern.
Persistente 
List rekursiv mit 
Kopf und 
Schwanz erstellt :
- Der Kopf ist das erste Element
- Schwanz - eine Liste mit den verbleibenden Elementen (diese Liste besteht auch aus Kopf und Schwanz)
Die 
List API enthält statische Factory-Methoden, mit denen Sie eine 
List erstellen können. Mit 
of() Methode static 
of() können Sie eine Instanz von 
List aus einem oder mehreren Objekten erstellen.
Sie können auch die statische Methode 
empty() verwenden, um eine leere 
List zu erstellen, und die Methode 
ofAll() , um eine 
List vom Typ 
Iterable zu erstellen:
 List < String > list = List.of( "Java", "PHP", "Jquery", "JavaScript", "JShell", "JAVA"); 
Schauen wir uns einige Beispiele für Listenmanipulationen an.
Wir können die 
drop() -Methode und ihre Varianten verwenden, um die ersten 
N Elemente zu entfernen:
 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) entfernt 
n Elemente aus der Liste, beginnend mit dem ersten Element, während 
dropRight() dasselbe tut, beginnend mit dem letzten Element in der Liste.
dropUntil() entfernt die Elemente aus der Liste, bis das Prädikat 
true , während 
dropWhile() die Elemente entfernt, bis das Prädikat 
true .
Es gibt auch die 
dropRightWhile() und 
dropRightUntil() , mit denen Elemente von rechts entfernt entfernt werden.
Als nächstes wird 
take(int n) verwendet, um Elemente aus der Liste abzurufen. Es nimmt 
n Elemente aus der Liste und stoppt dann. Es gibt auch 
takeRight(int n) , das Elemente vom Ende der Liste übernimmt:
 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); 
Schließlich nimmt 
takeUntil() Elemente aus der Liste, bis das Prädikat 
true . Es gibt eine Variante von 
takeWhile() , die auch ein Prädikatargument 
takeWhile() .
Darüber hinaus verfügt die API über andere nützliche Methoden, z. B. sogar 
distinct() , das eine Liste von Elementen mit gelöschten Duplikaten zurückgibt, sowie 
distinctBy() , das 
Comparator akzeptiert, um die Gleichheit zu bestimmen.
Es ist sehr interessant, dass es auch 
intersperse() , das ein Element zwischen jedes Element der Liste einfügt. Dies kann für Operationen mit 
String sehr praktisch sein:
 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"); 
Möchten Sie die Liste in Kategorien aufteilen? Und dafür gibt es eine 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); 
Die 
group(int n) -Methode teilt 
List in Gruppen von jeweils 
n Elementen auf. Die 
groupdBy() -Methode verwendet eine 
Function , die die Logik zum Aufteilen der Liste enthält, und gibt eine 
Map mit zwei Elementen zurück: 
true und 
false .
Der 
true Schlüssel wird der 
List Elemente zugeordnet, die die in 
Function angegebene Bedingung erfüllen. Der 
false Schlüssel wird der 
List Elemente zugeordnet, die diese Bedingung nicht erfüllen.
Wie erwartet ändert sich beim Ändern der 
List die ursprüngliche 
List nicht. Stattdessen 
List immer die neue Version von 
List zurückgegeben.
Wir können auch mit 
List interagieren, indem wir die Semantik des Stapels verwenden und Elemente nach dem LIFO-Prinzip (Last In, First Out) extrahieren. In diesem Sinne gibt es API-Methoden wie 
peek() , 
pop() und 
push() , um den Stapel zu manipulieren:
 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)); 
Mit der Funktion 
pushAll() wird ein Bereich von Ganzzahlen in den Stapel 
pushAll() , und mit der Funktion 
pushAll() wird das 
pushAll() des Stapels abgerufen. Es gibt auch eine 
peekOption() -Methode, mit der das Ergebnis in ein 
Option Objekt eingeschlossen werden kann.
Es gibt andere interessante und wirklich nützliche Methoden in der 
List Oberfläche, die in 
Java-Dokumenten gründlich dokumentiert sind.
4.2. Warteschlange
In der unveränderlichen 
Queue werden Elemente 
Queue , sodass Sie sie nach dem FIFO-Prinzip abrufen können (first in, first out).
Queue besteht aus zwei verknüpften Listen: der vorderen und der hinteren 
List . Die vordere 
List enthält Elemente, die aus der Warteschlange entfernt wurden, und die hintere 
List enthält die Elemente in der Warteschlange.
Auf diese Weise können Sie die Operationen zum Einreihen und Entfernen aus der Warteschlange auf die Komplexität 
O (1) setzen . Wenn die 
List in der vorderen 
List endet, wenn sie aus der Warteschlange entfernt wird, wird die hintere 
List umgekehrt und zur neuen vorderen 
List .
Erstellen wir eine Warteschlange:
 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))); 
Die Funktion 
dequeue() entfernt das head-Element aus der 
Queue und gibt 
Tuple2<T, Q> . Das erste Element des Tupels ist das aus der Warteschlange entfernte Kopfelement, das zweite Element des Tupels sind die verbleibenden 
Queue .
Wir können die 
combination(n) , um alle möglichen 
N Kombinationen von Elementen in der 
Queue :
 Queue < Queue < Integer >> queue1 = queue.combinations(2); assertEquals(queue1.get(2).toCharSeq(), CharSeq.of("23")); 
Auch hier ändert sich die ursprüngliche 
Queue beim Hinzufügen / Entfernen von Elementen zur Warteschlange nicht.
4.3. Stream
Stream ist eine Implementierung einer träge verknüpften Liste, die sich erheblich von 
java.util.stream . Im Gegensatz zu 
java.util.stream speichert 
Stream Vavr Daten und berechnet nachfolgende Elemente träge.
Angenommen, wir haben 
Stream Ganzzahlen:
 Stream < Integer > s = Stream.of(2, 1, 3, 4); 
Beim Drucken des Ergebnisses von 
s.toString() in der Konsole wird nur 
Stream (2,?) Angezeigt. Dies bedeutet, dass nur das 
Stream Kopfelement berechnet wurde, die Endelemente jedoch nicht.
s.get(3) Sie 
s.get(3) und dann das Ergebnis von 
s.tail() anzeigen, wird 
Stream (1, 3, 4 s.tail() . Im Gegenteil, wenn Sie nicht zuerst 
s.get(3) aufrufen, 
s.get(3) Stream das letzte Element berechnet, ist nur 
Stream (1 s.tail() ) Das Ergebnis von 
s.tail() ) . Dies bedeutet, dass nur das erste Endelement berechnet wurde.
Dieses Verhalten kann die Leistung verbessern und ermöglicht die Verwendung von 
Stream zur Darstellung von Sequenzen, die (theoretisch) unendlich lang sind.
Stream in Vavr ist unveränderlich und kann 
Empty oder 
Cons . 
Cons bestehen aus dem Kopfelement und dem träge berechneten Schwanz des 
Stream . Im Gegensatz zu 
List speichert 
Stream das head-Element im Speicher. Schwanzelemente werden nach Bedarf berechnet.
Erstellen wir einen 
Stream mit 10 positiven Ganzzahlen und berechnen die Summe der geraden Zahlen:
 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); 
Im Gegensatz zur 
Stream API von Java 8 ist 
Stream in Vavr eine Datenstruktur zum Speichern einer Folge von Elementen.
Daher verfügt es über Methoden wie 
get() , 
append() , 
insert() und andere zum Bearbeiten seiner Elemente. 
drop() , 
distinct() und einige andere zuvor diskutierte Methoden sind ebenfalls verfügbar.
Lassen Sie uns abschließend 
tabulate() in 
Stream demonstrieren. Diese Methode gibt einen 
Stream Länge 
n , der Elemente enthält, die das Ergebnis der Anwendung der Funktion sind:
 Stream < Integer > s1 = Stream.tabulate(5, (i) - > i + 1); assertEquals(s1.get(2).intValue(), 3); 
Wir können auch 
zip() , um einen 
Stream aus 
Tuple2<Integer, Integer> zu erstellen, der Elemente enthält, die durch Kombinieren von zwei 
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 ist eine unveränderliche indizierte Sequenz, die einen effizienten Direktzugriff ermöglicht. Es basiert auf einem Java- 
Array von Objekten. Im Wesentlichen ist dies ein 
Traversable Wrapper für ein Array von Objekten vom Typ 
TSie können eine Instanz von 
Array mit der statischen Methode 
of() erstellen. Darüber hinaus können Sie mit den statischen Methoden 
range() und 
rangeBy() eine Reihe von Elementen erstellen. Die 
rangeBy() -Methode verfügt über einen dritten Parameter, mit dem Sie den Schritt bestimmen können.
Die Methoden 
range() und 
rangeBy() erstellen Elemente, beginnend nur vom Anfangswert bis zum Endwert minus eins. Wenn wir den Endwert 
rangeClosed() , können wir 
rangeClosed() oder 
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); 
Lassen Sie uns mit den Elementen anhand des Index arbeiten:
 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 ist eine Kreuzung zwischen 
Array und 
List , die eine weitere indizierte Folge von Elementen bereitstellt und sowohl den wahlfreien Zugriff als auch die Änderung in konstanter Zeit ermöglicht:
 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 ist ein Sammlungsobjekt zur Darstellung einer Folge primitiver Zeichen. Im Wesentlichen ist dies ein Wrapper für 
String mit zusätzlichen Erfassungsoperationen.
Um 
CharSeq zu erstellen, müssen Sie Folgendes tun.
 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. Stellen Sie ein
In diesem Abschnitt werden die verschiedenen Implementierungen von 
Set in der Sammlungsbibliothek erläutert. Ein einzigartiges Merkmal der 
Set Datenstruktur ist, dass keine doppelten Werte zulässig sind.
Es gibt verschiedene Implementierungen von 
Set . Das wichtigste ist 
HashSet . 
TreeSet erlaubt keine doppelten Elemente und kann sortiert werden. 
LinkedHashSet die 
LinkedHashSet der Elemente bei.
Schauen wir uns diese Implementierungen nacheinander genauer an.
5.1. Hashset
HashSet verfügt über statische Factory-Methoden zum Erstellen neuer Instanzen. Einige davon haben wir weiter oben in diesem Artikel untersucht, zum Beispiel 
of() , 
ofAll() und Variationen der 
range() -Methoden.
Die Differenz zwischen den beiden 
Mengen kann mit der 
diff() -Methode ermittelt werden. Außerdem geben die Methoden 
union() und 
intersect() die Vereinigung und den Schnittpunkt zweier 
Mengen zurück :
 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)); 
Wir können auch grundlegende Operationen ausführen, z. B. das Hinzufügen und Entfernen von Elementen:
 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")); 
Die 
HashSet Implementierung basiert auf dem 
Hash Array Mapped Trie (HAMT) , das im Vergleich zur üblichen 
HashTable eine überlegene Leistung 
HashTable und aufgrund seiner Struktur für die Unterstützung persistenter Sammlungen geeignet ist.
5.2. Baumset
TreeSet ist eine Implementierung der 
SortedSet Schnittstelle. Es speichert eine Reihe sortierter Elemente und wird mithilfe von binären Suchbäumen implementiert. Alle seine Operationen werden während der 
O (log n) Zeit ausgeführt .
Standardmäßig werden 
TreeSet Elemente in ihrer natürlichen Reihenfolge sortiert.
Erstellen wir ein 
SortedSet mit einer natürlichen Sortierreihenfolge:
 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()); 
TreeSet beim Erstellen des 
TreeSet eine 
Comparator Instanz, um Elemente auf benutzerdefinierte Weise 
TreeSet . Sie können eine Zeichenfolge auch aus einer Reihe von Elementen erstellen:
 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
Vavr-Sammlungen haben auch eine unveränderliche 
BitSet Implementierung. Die 
BitSet Schnittstelle erweitert die 
SortedSet Schnittstelle. 
BitSet kann mit statischen Methoden in 
BitSet.Builder .
Wie bei anderen Implementierungen der 
Set Datenstruktur können Sie mit 
BitSet keine doppelten Datensätze zu einem Set hinzufügen.
Es erbt Manipulationsmethoden von der 
Traversable Schnittstelle. Beachten Sie, dass es sich von 
java.util.BitSet von der Standard-Java-Bibliothek unterscheidet. 
BitSet Daten dürfen keine 
String Werte enthalten.
Erstellen Sie eine Instanz von 
BitSet mit der Factory-Methode 
of() :
 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); 
Um die ersten vier 
BitSet Elemente auszuwählen 
BitSet wir den Befehl 
takeUntil() . Die Operation hat eine neue Instanz zurückgegeben. Beachten Sie, dass die 
takeUntil() -Methode in der 
Traversable Schnittstelle definiert ist, die die übergeordnete Schnittstelle für 
BitSet .
Andere oben in der 
Traversable Schnittstelle definierte Methoden und Operationen gelten auch für 
BitSet .
6. Karte
Map ist eine Schlüsselwertdatenstruktur. 
Map in Vavr ist unveränderlich und verfügt über Implementierungen für 
HashMap , 
TreeMap und 
LinkedHashMap .
In der Regel lassen 
Kartenverträge keine doppelten Schlüssel zu, während doppelte Werte, die verschiedenen Schlüsseln zugeordnet sind, möglicherweise doppelt vorhanden sind.
6.1. Hashmap
HashMap ist eine Implementierung der unveränderlichen 
Map Schnittstelle. Es speichert Schlüssel-Wert-Paare unter Verwendung eines Hash von Schlüsseln.
Map in Vavr verwendet 
Tuple2 , um Schlüssel-Wert-Paare anstelle des herkömmlichen Eintragstyps 
Tuple2 :
 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()); 
Wie bei 
HashSet basiert die Implementierung von 
HashMap auf dem 
Hash Array Mapped Trie (HAMT) , was zu einer konstanten Zeit für fast alle Operationen führt.
filterKeys() können mit der Methode 
filterKeys() nach Schlüsseln oder mit der Methode 
filterKeys() nach Werten 
filterValues() werden. Beide Methoden verwenden 
Predicate als Argument:
 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")); 
Sie können 
Kartenelemente auch mit der 
map() -Methode transformieren. Konvertieren 
wir beispielsweise 
map1 in 
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. Baumkarte
TreeMap ist eine Implementierung der 
SortedMap Schnittstelle. Wie bei 
TreeSet wird eine benutzerdefinierte Instanz von 
Comparator verwendet, um die Sortierung von 
TreeMap Elementen 
TreeMap .
SortedMap die Erstellung von 
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()); 
Standardmäßig werden 
TreeMap Einträge in der Reihenfolge der natürlichen Schlüssel sortiert. Sie können jedoch den 
Comparator angeben, der zum Sortieren verwendet werden soll:
 TreeMap < Integer, String > treeMap2 = TreeMap.of(Comparator.reverseOrder(), 3, "three", 6, "six", 1, "one"); assertEquals(treeMap2.keySet().mkString(), "631"); 
Wie im Fall von 
TreeSet wird auch die 
TreeMap Implementierung unter Verwendung des Baums erstellt, daher haben ihre Operationen die Zeit 
O (log n) . Die 
map.get(key) -Methode gibt 
Option , die den Wert des angegebenen 
Map- Schlüssels enthält.
7. Java-Kompatibilität
Die Vavr Collection-API ist vollständig kompatibel mit dem Java Collection Framework. Mal sehen, wie das in der Praxis gemacht wird.
7.1. Konvertieren Sie von Java nach Vavr
Jede Auflistungsimplementierung in Vavr verfügt über eine statische Factory 
ofAll() -Methode, die 
java.util.Iterable akzeptiert. Auf diese Weise können Sie eine 
Vavr- Sammlung aus einer 
Java- Sammlung erstellen. In ähnlicher Weise akzeptiert eine andere 
ofAll() Factory-Methode direkt Java 
Stream .
So konvertieren Sie eine Java- 
List in eine unveränderliche 
List :
 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); 
Eine weitere nützliche Funktion ist 
collector() , die in Verbindung mit 
Stream.collect() , um die Vavr-Sammlung abzurufen:
 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. Konvertieren Sie von Vavr nach Java
Die 
Value Schnittstelle verfügt über viele Methoden zum Konvertieren von einem 
Vavr- Typ in einen 
Java- Typ. Diese Methoden haben das Format 
toJavaXXX() .
Betrachten Sie einige Beispiele:
 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()); 
Wir können auch Java 8 
Collectors , um Objekte aus Vavr-Sammlungen zu sammeln:
 java.util.Set < Integer > javaSet = List.of(1, 2, 3) .collect(Collectors.toSet()); assertEquals(3, javaSet.size()); assertEquals(1, javaSet.toArray()[0]); 
7.3. Java-Sammlungsansichten
Darüber hinaus bietet die Bibliothek sogenannte 
Sammlungsansichten , die bei der Konvertierung in Java-Sammlungen am besten funktionieren. Die Transformationsmethoden im vorherigen Abschnitt durchlaufen alle Elemente, um eine Java-Sammlung zu erstellen.
Ansichten hingegen implementieren Standard-Java-Schnittstellen und delegieren Methodenaufrufe an die Vavr-Basissammlung.
Zum Zeitpunkt dieses Schreibens wird nur die 
List unterstützt. Jede sequentielle Sammlung verfügt über zwei Methoden: eine zum Erstellen einer unveränderlichen Darstellung, die andere zum Ändern.
Das Aufrufen von Methoden zum Ändern einer unveränderlichen Ansicht 
UnsupportedOperationException .
Schauen wir uns ein Beispiel an:
 @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); } 
So erstellen Sie eine unveränderliche Ansicht:
 java.util.List < Integer > javaList = List.of(1, 2, 3) .asJavaMutable(); javaList.add(4); assertEquals(4, javaList.get(3).intValue()); 
8. Schlussfolgerungen
In diesem Tutorial haben wir die verschiedenen funktionalen Datenstrukturen kennengelernt, die von der Vavr Collections-API bereitgestellt werden. Es gibt auch nützliche und produktive API-Methoden, die im 
Java-Dokument und 
im Vavr Collections- 
Benutzerhandbuch enthalten sind .
Schließlich ist zu beachten, dass die Bibliothek auch 
Try , 
Option , 
Either und 
Future , wodurch die 
Value Schnittstelle erweitert und infolgedessen die Java 
Iterable Schnittstelle 
Iterable wird. Dies bedeutet, dass sie sich in einigen Situationen wie Sammlungen verhalten können.
Den vollständigen Quellcode für alle Beispiele in diesem Artikel finden Sie auf 
Github .
Zusätzliche Materialien:
habr.com/de/post/421839www.baeldung.com/vavrÜbersetzt von 
@middle_java