VAVR (anciennement Javaslang) est une bibliothèque fonctionnelle à but non lucratif pour Java 8+. Il vous permet d'écrire du code fonctionnel de type Scala en Java et sert à réduire la quantité de code et à améliorer sa qualité.
Site de la bibliothèque .
Sous la coupe se trouve une traduction d'un article systématisant les informations sur
l'API Vavr Collections .
Traduit par
@middle_javaDernière modification de l'article original: 15 août 2019
1. Présentation
La bibliothèque Vavr, précédemment connue sous le nom de Javaslang, est une bibliothèque fonctionnelle pour Java. Dans cet article, nous explorons sa puissante API de collecte.
Consultez
cet article pour plus d'informations sur cette bibliothèque.
2. Collections persistantes
Une collection persistante, lorsqu'elle est modifiée, crée une nouvelle version de la collection sans changer la version actuelle.
La prise en charge de plusieurs versions de la même collection peut entraîner une utilisation inefficace du processeur et de la mémoire. Cependant, la bibliothèque de collections Vavr surmonte cela en partageant la structure de données entre différentes versions de la collection.
Ceci est fondamentalement différent de
unmodifiableCollection()
de la classe d'utilitaires Java
Collections
, qui fournit simplement un wrapper pour la collection de base.
Tenter de modifier une telle collection
UnsupportedOperationException
au lieu de créer une nouvelle version. De plus, la collection de base est toujours modifiable par un lien direct avec elle.
3. Traversable
Traversable
est le type de base de toutes les collections Vavr. Cette interface définit des méthodes communes à toutes les structures de données.
Il fournit des méthodes par défaut utiles, telles que
size()
,
get()
,
filter()
,
isEmpty()
et d'autres héritées des sous-interfaces.
Nous explorons davantage la bibliothèque de la collection.
4. Seq
Commençons par les séquences.
L'interface
Seq
est une structure de données séquentielle. Il s'agit de l'interface parent pour
List
,
Stream
,
Queue
,
Array
,
Vector
et
CharSeq
. Toutes ces structures de données ont leurs propres propriétés uniques, dont nous parlerons ci-dessous.
4.1. Liste
List
est une opération calculée énergiquement (évaluée avec impatience, est effectuée dès que les valeurs de ses opérandes sont connues) une séquence d'éléments qui étendent l'interface
LinearSeq
.
Les
List
persistantes
List
construites récursivement en utilisant la
tête et la
queue :
- La tête est le premier élément
- Queue - une liste contenant les éléments restants (cette liste est également formée de la tête et de la queue)
L'API
List
contient des méthodes d'usine statiques que vous pouvez utiliser pour créer une
List
. Vous pouvez utiliser la méthode static
of()
pour créer une instance de
List
partir d'un ou plusieurs objets.
Vous pouvez également utiliser la méthode static
empty()
pour créer une
List
vide et la méthode
ofAll()
pour créer une
List
de type
Iterable
:
List < String > list = List.of( "Java", "PHP", "Jquery", "JavaScript", "JShell", "JAVA");
Regardons quelques exemples de manipulation de liste.
Nous pouvons utiliser la méthode
drop()
et ses variantes pour supprimer les premiers
N
éléments:
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)
supprime
n
éléments de la liste, à partir du premier élément, tandis que
dropRight()
fait de même, à partir du dernier élément de la liste.
dropUntil()
supprime les éléments de la liste jusqu'à ce que le prédicat soit
true
, tandis que
dropWhile()
supprime les éléments jusqu'à ce que le prédicat soit
true
.
Il existe également des
dropRightWhile()
et
dropRightUntil()
qui suppriment les éléments en partant de la droite.
Ensuite,
take(int n)
utilisé pour récupérer des éléments de la liste. Il prend
n
éléments de la liste puis s'arrête. Il y a aussi
takeRight(int n)
, qui prend des éléments de la fin de la liste:
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);
Enfin,
takeUntil()
prend des éléments de la liste jusqu'à ce que le prédicat devienne
true
. Il existe une variante de
takeWhile()
qui prend également un argument de prédicat.
De plus, l'API a d'autres méthodes utiles, par exemple même
distinct()
, qui renvoie une liste d'éléments avec des doublons supprimés, ainsi que
distinctBy()
, qui accepte
Comparator
pour déterminer l'égalité.
Il est très intéressant qu'il y ait aussi
intersperse()
, qui insère un élément entre chaque élément de la liste. Cela peut être très pratique pour les opérations avec
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");
Vous voulez diviser la liste en catégories? Et pour cela il y a une 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);
La méthode
group(int n)
divise
List
en groupes de
n
éléments chacun. La méthode
groupdBy()
prend une
Function
qui contient la logique de fractionnement de la liste et renvoie une
Map
avec deux éléments:
true
et
false
.
La
true
clé est mappée sur la
List
éléments satisfaisant à la condition spécifiée dans
Function
. La
false
clé correspond à la
List
éléments qui ne remplissent pas cette condition.
Comme prévu, lors de la modification de la
List
, la
List
origine ne change pas réellement. Au lieu de cela, la nouvelle version de
List
toujours renvoyée.
Nous pouvons également interagir avec
List
utilisant la sémantique de la pile - extraire des éléments selon le principe «dernier entré, premier sorti» (LIFO). En ce sens, des méthodes API telles que
peek()
,
pop()
et
push()
existent pour manipuler la pile:
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));
La fonction
pushAll()
est utilisée pour insérer une plage d'entiers sur la pile, et la fonction
peek()
est utilisée pour récupérer l'élément head de la pile. Il existe également une méthode
peekOption()
qui peut encapsuler le résultat dans un objet
Option
.
Il existe d'autres méthodes intéressantes et vraiment utiles dans l'interface
List
qui sont documentées en
détail dans les documents
Java .
4.2. File d'attente
La
Queue
immuable stocke les éléments, vous permettant de les récupérer selon le principe FIFO (premier entré, premier sorti).
Queue
intérieur se compose de deux listes liées: la
List
avant et la
List
arrière. La
List
avant contient les éléments qui sont supprimés de la file d'attente et la
List
arrière contient les éléments mis en file d'attente.
Cela vous permet de mettre les opérations de mise en file d'attente et de retrait de la file d'attente à la complexité
O (1) . Lorsque la
List
se termine dans la
List
avant lorsqu'elle est supprimée de la file d'attente, la
List
arrière
List
inversée et devient la nouvelle
List
avant.
Créons une file d'attente:
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)));
La fonction
dequeue()
supprime l'élément head de
Queue
et renvoie
Tuple2<T, Q>
. Le premier élément du tuple est l'élément head retiré de la file d'attente, le deuxième élément du tuple est le reste des éléments
Queue
.
Nous pouvons utiliser la
combination(n)
pour obtenir toutes les
N
combinaisons possibles d'éléments dans la
Queue
:
Queue < Queue < Integer >> queue1 = queue.combinations(2); assertEquals(queue1.get(2).toCharSeq(), CharSeq.of("23"));
Encore une fois, la
Queue
origine ne change pas lors de l'ajout / suppression d'éléments de la file d'attente.
4.3. Stream
Stream
est une implémentation d'une liste liée paresseusement qui est significativement différente de
java.util.stream
. Contrairement à
java.util.stream
,
Stream
Vavr stocke les données et calcule paresseusement les éléments suivants.
Disons que nous avons des entiers
Stream
:
Stream < Integer > s = Stream.of(2, 1, 3, 4);
Lors de l'impression du résultat de
s.toString()
dans la console, seul
Stream (2 ,?) sera affiché. Cela signifie que seul l'élément de tête de
Stream
été calculé, alors que les éléments de queue ne l'ont pas été.
Appeler
s.get(3)
puis afficher le résultat de
s.tail()
renvoie
Stream (1, 3, 4 ,?) . Au contraire, si vous n'appelez pas d'abord
s.get(3)
- ce qui fera que
Stream
calculera le dernier élément - seul
Stream (1 ,?) sera le résultat de
s.tail()
) . Cela signifie que seul le premier élément de queue a été calculé.
Ce comportement peut améliorer les performances et permet à
Stream
d'être utilisé pour représenter des séquences qui sont (théoriquement) infiniment longues.
Stream
dans Vavr est immuable et peut être
Empty
ou
Cons
.
Cons
composent de l'élément de tête et de la queue calculée paresseusement du
Stream
. Contrairement à
List
,
Stream
stocke que l'élément head en mémoire. Les éléments de queue sont calculés selon les besoins.
Créons un
Stream
de 10 entiers positifs et calculons la somme des nombres pairs:
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);
Contrairement à l'API
Stream
de Java 8,
Stream
dans Vavr est une structure de données pour stocker une séquence d'éléments.
Par conséquent, il a des méthodes telles que
get()
,
append()
,
insert()
et autres pour manipuler ses éléments.
drop()
,
distinct()
et certaines autres méthodes décrites précédemment sont également disponibles.
Enfin, montrons rapidement
tabulate()
dans
Stream
. Cette méthode retourne un
Stream
longueur
n
contenant des éléments qui sont le résultat de l'application de la fonction:
Stream < Integer > s1 = Stream.tabulate(5, (i) - > i + 1); assertEquals(s1.get(2).intValue(), 3);
Nous pouvons également utiliser
zip()
pour créer un
Stream
partir de
Tuple2<Integer, Integer>
, qui contient des éléments formés en combinant deux
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
est une séquence indexée immuable qui fournit un accès aléatoire efficace. Il est basé sur un
tableau d' objets Java. Il s'agit essentiellement d'un wrapper
Traversable
pour un tableau d'objets de type
T
Vous pouvez créer une instance d'
Array
à l'aide de la méthode static
of()
. De plus, vous pouvez créer une plage d'éléments à l'aide des méthodes statiques
range()
et
rangeBy()
. La méthode
rangeBy()
possède un troisième paramètre qui vous permet de déterminer l'étape.
Les méthodes
range()
et
rangeBy()
créeront des éléments, en commençant uniquement de la valeur initiale à la valeur finale moins un. Si nous devons inclure la valeur finale, nous pouvons utiliser
rangeClosed()
ou
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);
Travaillons avec les éléments en utilisant l'index:
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. Vecteur
Vector
est un croisement entre
Array
et
List
, fournissant une autre séquence indexée d'éléments, permettant à la fois un accès aléatoire et une modification en temps constant:
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
est un objet de collection pour représenter une séquence de caractères primitifs. Il s'agit essentiellement d'un wrapper pour
String
avec l'ajout d'opérations de collecte.
Pour créer
CharSeq
vous devez procéder comme suit.
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. Définir
Cette section présente les différentes implémentations de
Set
dans la bibliothèque de collections. Une caractéristique unique de la structure de données
Set
est qu'elle n'autorise pas les valeurs en double.
Il existe différentes implémentations de
Set
. Le principal est
HashSet
.
TreeSet
n'autorise pas les éléments en double et peut être trié.
LinkedHashSet
préserve l'ordre d'insertion des éléments.
Examinons ces implémentations de plus près.
5.1. Hashset
HashSet
a des méthodes d'usine statiques pour créer de nouvelles instances. Nous avons étudié certaines d'entre elles plus haut dans cet article, par exemple les
ofAll()
et les variations des méthodes
range()
.
La différence entre les deux
ensembles peut être obtenue en utilisant la méthode
diff()
. De plus, les méthodes
union()
et
intersect()
renvoient l'union et l'intersection de deux
ensembles :
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));
Nous pouvons également effectuer des opérations de base, telles que l'ajout et la suppression d'éléments:
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"));
L'implémentation
HashSet
est basée sur le
trieur de tableaux Hash (HAMT) , qui offre des performances supérieures par rapport à
HashTable
et sa structure le rend approprié pour prendre en charge les collections persistantes.
5.2. Treeset
TreeSet
est une implémentation de l'interface
SortedSet
. Il stocke un ensemble d'éléments triés et est implémenté à l'aide d'arbres de recherche binaires. Toutes ses opérations sont effectuées pendant le temps
O (log n) .
Par défaut, les éléments
TreeSet
sont triés dans leur ordre naturel.
Créons un
SortedSet
utilisant un ordre de tri naturel:
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());
Pour organiser les éléments de manière personnalisée, transmettez une instance de
Comparator
lors de la création du
TreeSet
. Vous pouvez également créer une chaîne à partir d'un ensemble d'éléments:
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
Les collections Vavr ont également une implémentation
BitSet
immuable. L'interface
BitSet
étend l'interface
BitSet
.
BitSet
peut être créé à l'aide de méthodes statiques dans
BitSet.Builder
.
Comme avec d'autres implémentations de la structure de données
Set
,
BitSet
ne vous permet pas d'ajouter des enregistrements en double à un ensemble.
Il hérite des méthodes de manipulation de l'interface
Traversable
. Notez qu'il est différent de
java.util.BitSet
de la bibliothèque Java standard.
BitSet
données
BitSet
ne peuvent pas contenir de valeurs de
String
.
Envisagez de créer une instance de
BitSet
à l'aide de la méthode d'usine
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);
Pour sélectionner les quatre
BitSet
éléments
BitSet
nous avons utilisé la commande
takeUntil()
. L'opération a renvoyé une nouvelle instance. Notez que la méthode
takeUntil()
est définie dans l'interface
Traversable
, qui est l'interface parent de
BitSet
.
Les autres méthodes et opérations décrites ci-dessus définies dans l'interface
Traversable
s'appliquent également à
BitSet
.
6. Carte
Map
est une structure de données de valeur-clé.
Map
dans Vavr est immuable et comporte des implémentations pour
HashMap
,
TreeMap
et
LinkedHashMap
.
En règle générale, les contrats de
carte n'autorisent pas les clés en double, tandis que les valeurs en double mappées sur différentes clés peuvent l'être.
6.1. Hashmap
HashMap
est une implémentation de l'interface
Map
immuable. Il stocke les paires clé-valeur à l'aide d'un hachage de clés.
Map
dans Vavr utilise
Tuple2
pour représenter des paires clé-valeur au lieu du type d'
Entry
traditionnel:
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());
Comme
HashSet
, l'implémentation de
HashMap
basée sur le
trieur de tableaux Hash (HAMT) , ce qui conduit à un temps constant pour presque toutes les opérations.
Les éléments de
carte peuvent être filtrés par clé à l'aide de la méthode
filterKeys()
ou par valeur à l'aide de la méthode
filterValues()
. Les deux méthodes prennent
Predicate
comme 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"));
Vous pouvez également transformer des éléments de
carte à l'aide de la méthode
map()
. Par exemple, convertissons
map1 en
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
est une implémentation de l'interface
SortedMap
. Comme avec
TreeSet
, une instance personnalisée de
Comparator
utilisée pour personnaliser le tri des éléments
TreeMap
.
SortedMap
la création de
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());
Par défaut, les entrées
TreeMap
sont triées dans l'ordre des clés naturelles. Cependant, vous pouvez spécifier le
Comparator
à utiliser pour le tri:
TreeMap < Integer, String > treeMap2 = TreeMap.of(Comparator.reverseOrder(), 3, "three", 6, "six", 1, "one"); assertEquals(treeMap2.keySet().mkString(), "631");
Comme dans le cas de
TreeSet
, l'implémentation
TreeMap
est également créée à l'aide de l'arbre, par conséquent, ses opérations ont le temps
O (log n) . La
map.get(key)
renvoie
Option
, qui contient la valeur de la clé de
carte spécifiée.
7. Compatibilité Java
L'API Vavr Collection est entièrement compatible avec Java Collection Framework. Voyons comment cela se fait dans la pratique.
7.1. Convertir de Java à Vavr
Chaque implémentation de collection dans Vavr possède une
ofAll()
fabrique statique
ofAll()
qui accepte
java.util.Iterable
. Cela vous permet de créer une collection
Vavr à partir d'une collection
Java . De même, une autre méthode d'usine
ofAll()
accepte directement Java
Stream
.
Pour convertir une
List
Java en une
List
immuable:
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);
Une autre fonction utile est
collector()
, qui peut être utilisée en conjonction avec
Stream.collect()
pour obtenir la collection 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. Convertir de Vavr à Java
L'interface
Value
possède de nombreuses méthodes de conversion d'un type
Vavr vers un type
Java . Ces méthodes ont le format
toJavaXXX()
.
Prenons quelques exemples:
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());
Nous pouvons également utiliser Java 8
Collectors
pour collecter des éléments des collections 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. Vues des collections Java
De plus, la bibliothèque propose
des vues de collection qui fonctionnent mieux lorsqu'elles sont converties en collections Java. Les méthodes de transformation de la section précédente itèrent sur (itèrent) tous les éléments pour créer une collection Java.
Les vues, quant à elles, implémentent des interfaces Java standard et délèguent les appels de méthode à la collection de base Vavr.
Au moment d'écrire ces lignes, seule la vue
List
est prise en charge. Chaque collection séquentielle a deux méthodes: l'une pour créer une représentation immuable, l'autre pour mutable.
L'appel de méthodes pour modifier une vue immuable
UnsupportedOperationException
.
Regardons un exemple:
@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); }
Pour créer une vue immuable:
java.util.List < Integer > javaList = List.of(1, 2, 3) .asJavaMutable(); javaList.add(4); assertEquals(4, javaList.get(3).intValue());
8. Conclusions
Dans ce didacticiel, nous avons découvert les différentes structures de données fonctionnelles fournies par l'API Vavr Collections. Il existe également des méthodes API utiles et productives qui peuvent être trouvées dans la
documentation Java et
le Guide de l'
utilisateur des collections Vavr.
Enfin, il est important de noter que la bibliothèque définit également
Try
,
Option
,
Either
et
Future
, qui étendent l'interface
Value
et, par conséquent, implémentent l'interface Java
Iterable
. Cela signifie que dans certaines situations, ils peuvent se comporter comme des collections.
Le code source complet de tous les exemples de cet article se trouve sur
Github .
Matériaux supplémentaires:
habr.com/en/post/421839www.baeldung.com/vavrTraduit par
@middle_java