web-dev-qa-db-fra.com

Utilisation de Java 8 Facultatif pour la liste de chaînes en sortie

Je veux utiliser facultatif pour une méthode qui renvoie une liste

Disons que la fonction est

public Output getListOfSomething() {
    // In some cases there is nothing to return and hence it makes sense to have return 
    // type as Optional here
}

Par conséquent, la fonction ressemble à:

public Optional<List<String>> getListOfSomething() {
    // return something only when there is some valid list
}

Maintenant, je veux faire quelque chose si la liste est présente donc quelque chose comme:

Optional<List<String>> listOfSomething = getListOfSomething();

int size = 0;

listOfSomething.ifPresent(size = listOfSomething.get().size());

Je suis nouveau sur Facultatif et j'ai parcouru les articles sur Facultatif et il semble que cela devrait fonctionner mais je reçois une erreur de syntaxe dans mon IDE:

la méthode ifPresent n'est pas applicable aux arguments (void).

Je voulais obtenir de l'aide de développeurs qui pourraient être plus à l'aise avec les lamdas dans Java 8.

9
Scorpion

Il est important de penser à la sémantique ici.

Votre méthode peut renvoyer une liste ou "aucune liste".

S'il renvoie une liste, il peut renvoyer une liste vide.

Vous devriez vous demander, "y a-t-il une raison sémantique pour faire la distinction entre une liste vide et aucune liste?" Parfois, il y a une bonne raison de faire la différence, mais c'est rare. Réfléchissez longuement avant de décider que Empty et Null sont différents dans votre cas. Une partie de la raison pour éviter No List est qu'elle réduit les "cas spéciaux" que le code client doit prendre en compte. Par exemple, s'ils doivent faire quelque chose pour chaque élément retourné, mais vous pouvez également retourner null, ils doivent effectuer une vérification spéciale pour null avant d'entrer dans un pour chaque boucle. Un pour chacun ne fait rien si la liste est vide.

Si une "No List" est distincte d'une "Empty List" dans votre domaine problématique, il est parfois utile de renvoyer une classe wrapper qui aide le code client à distinguer ces conditions et à les gérer de manière appropriée. Optional est une de ces classes génériques, mais votre domaine peut demander quelque chose de plus spécifique (même s'il imite la fonctionnalité d'Optional, il pourrait avoir une meilleure définition sémantique).

19
Daniel

La véritable méthode de programmation fonctionnelle est la suivante:

size = listOfSomething.map(List::size).orElse(0);

Mais il serait préférable de renvoyer un List vide au lieu de Optional.

17
Tagir Valeev

ifPresent nécessite une interface Consumer pour fonctionner. Vous pouvez effectuer les opérations suivantes:

Optional<List<String>> listOfSomething = getListOfSomething();
Integer[] size = {0};
listOfSomething.ifPresent(list -> size[0]=list.size())

Mais comme indiqué par Tagir Valeev il vaudrait mieux faire:

size = listOfSomething.map(List::size).orElse(0);

Et il serait également préférable de renvoyer une liste vide ou même un flux peut-être.

5
pbod