42 votes

Existe-t-il une classe comme Optional mais pour les non-optionnels ?

Il est pratique de déclarer des fonctions pour mapper les valeurs et les consommer si elles sont présentes.

Dans le cas où vous avez plusieurs objets obligatoires, et plusieurs Optionals, je me retrouve à envelopper les autres dans Optional.of(mandatoryObject) également afin de pouvoir utiliser les mêmes expressions sur eux sans tout écrire à l'envers.

Food vegetables = Food.someVegetables();
Optional<Food> condiment = Food.someCondiment();
Optional<Food> spices = Food.someSpices();

condiment.map(prepare).ifPresent(putOnPlate);
spices.map(prepare).ifPresent(putOnPlate);

Mais alors je n'aime pas ce code :

putOnPlate.accept(prepare.apply(vegetables));

alors je l'emballe :

Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);

Mais c'est tout simplement faux, car les légumes (dans cet exemple) ne sont en fait pas facultatifs. Ils sont très importants et je viens de donner à tout le monde l'impression qu'ils sont facultatifs.

Ma question est donc la suivante : Existe-t-il une classe en java comme java.util.Mandatory pour que je puisse écrire :

Mandatory.of(vegetables).map(prepare).definitelyPresentSo(putOnPlate);

27voto

Holger Points 13789

Oui, une telle API existe. Vous pouvez remplacer

Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);

avec

Stream.of(vegetables).map(prepare).forEach(putOnPlate);

doivent maintenant vivre avec le fait que l'élément simple Stream est un cas particulier du flux d'éléments arbitraires (y compris le flux vide éventuel).

Mais vous pouvez traiter tous les éléments obligatoires en même temps

Stream.of(mandatory1, mandatory2, mandatory3 /* etc */).map(prepare).forEach(putOnPlate);

Il serait même possible d'intégrer les éléments facultatifs, mais ce ne sera pas aussi pratique que cela devrait l'être, car Optional.stream() ne sera pas introduit avant Java 9.

10voto

Grzegorz Piwowarek Points 7040

L'idée principale derrière Optional est d'abstraire la nullité (en se débarrassant des contrôles de nullité) et de fournir une API fluide pour travailler avec des valeurs optionnelles.

Dans le cas d'une valeur toujours présente, il n'y a rien à abstraire (du moins rien qui ait une valeur pratique), de sorte que de tels outils n'existent pas dans le Java pur.

Dans d'autres langages fonctionnels, vous disposez de plusieurs outils "monadiques" tels que Optional disponibles pour différents cas d'utilisation. Si vous voulez les amener à Java, Javaslang est probablement le meilleur endroit où regarder. Vous pouvez y trouver des outils comme Option , Try , Lazy , Validation , Either , Future , Tuple et l'ensemble Collections API qui permet de coder d'une manière similaire à celle que vous avez décrite.

4voto

Anton Balaniuc Points 4529

Je me trompe peut-être, mais si tu n'aimes pas utiliser Optional vous pouvez simplement utiliser un Stream d'un seul objet. Ainsi, au lieu de

Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);

vous pouvez simplement utiliser :

Stream.of(vegetables).map(prepare).forEach(putOnPlate); 

Le résultat sera identique. Les deux méthodes vont lancer NPE si les légumes sont nuls.

Arrays.asList(10, null).forEach(value -> {
        Optional.of(value).map(x -> x.toString()).ifPresent(System.out::println);
        Stream.of(value).map(x -> x.toString()).forEach(System.out::println);
});

La version sécurisée NPE sera

 Optional.ofNullable(value).map(x -> x.toString()).ifPresent(System.out::println);
 Stream.of(value).filter(Objects::nonNull).map(x -> x.toString()).forEach(System.out::println);

Optional est juste un conteneur pour un objet qui peut ou non contenir une valeur non nulle.

0voto

Stephan Herrmann Points 1860

Vous semblez chercher le type @NonNull Food .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X