2
votes

Comment retourner null lorsque la liste est vide dans Java 8?

Comment puis-je changer cette méthode pour qu'elle renvoie null si la liste passée en paramètre est vide sans utiliser une instruction if ?

 default String getFiltersExpression(List<WorklistViewDto.Filter> filters) {
    return Optional.ofNullable(filters)
        .map(Collection::stream)
        .orElseGet(Stream::empty)
        .map(WorkListViewMapper::formatValue)
        .map(f -> f.getCriteria() + f.getOperator() + f.getValue())
        .collect(Collectors.joining(" AND ", "(", ")"));
}


11 commentaires

return Facultatif ... ouElse (null); ( List n'est pas un tableau )


Il n'y a pas de tableaux ici. Vous voulez dire la liste?


oui la liste désolé.


le problème ici est si je mets orElse (null) ou .orElseGet (Stream :: empty) ou orElseGet (null). la méthode renvoie une chaîne = "()"


Et une bonne vieille instruction if ?


Pourquoi retourner null, pas facultatif? Renvoyer null est toujours la première étape vers un NPE.


En fait, s'il n'y a pas de filtres (même si son null ) quel est le mal à renvoyer "()" ?


cette valeur est passée à un WS distant qui n'accepte pas cette valeur j'ai besoin qu'elle soit nulle si la liste est vide


quelqu'un peut-il m'aider à corriger ce code sans utiliser si


Êtes-vous en train de créer une instruction SQL?


Pourquoi vouloir retourner null en premier lieu? Une liste vide est plus sûre et tout aussi utile dans presque tous les cas.


3 Réponses :


2
votes

Je recommanderais de ne pas renvoyer null et plutôt de renvoyer une chaîne "()" comme expression de filtre pour cela, vous pouvez simplement ajouter un filtre pour une liste vide sous la forme:

String getFiltersExpressions(List<Filter> filters) {
    return Stream.ofNullable(filters)
            .flatMap(Collection::stream)
            .map(WorkListViewMapper::formatValue)
            .map(f -> f.getCriteria() + f.getOperator() + f.getValue())
            .collect(Collectors.joining(" AND ", "(", ")"));
}


2 commentaires

L'OP veut retourner null lorsque la liste est vide, ne pas traiter une entrée null comme une liste vide. De plus, l'étape .filter (l ->! L.isEmpty ()) de la première variante est obsolète.


@Holger d'accord. Ceci est une recommandation plus que la sortie souhaitée. Oui, j'y pensais, si le Collection :: stream devait suffire à créer Stream.empty dans la première variante, auquel cas le code réel d'OP ferait de même opération.



3
votes

Vous pouvez le faire avec Collectors.collectingAndThen .

Collectors.collectingAndThen(
    Collectors.joining(" AND "), 
    str->{
            if(str.isEmpty()) return null; 
            return "(" + str + ")";
    })

Compte tenu de la déclaration de jonction de OP, Collectors.joining (" AND "," (",") ") nous pourrions modifier ce qui précède.

.collect( 
    Collectors.collectingAndThen(
        Collectors.joining(), 
        str->{
            if(str.isEmpty()) return null; 
            return str;
        }
     )
 );


2 commentaires

Je soupçonne que le problème ici serait que le str ne serait plus vide après l'opération join comme dans la question. Il doit simplement renvoyer "()" à ce que je peut deviner .


@nullpointer Je l'éditerai, mon point était plutôt d'utiliser un autre collecteur.



1
votes

Une autre méthode consiste à démarrer la diffusion uniquement si la liste est non nulle et non vide:

default String getFiltersExpression(List<WorklistViewDto.Filter> filters) {
    return Optional.ofNullable(filters)
            .filter(fs -> !fs.isEmpty())
            .map(fs -> fs.stream()
                    .map(WorkListViewMapper::formatValue)
                    .map(f -> f.getCriteria() + f.getOperator() + f.getValue())
                    .collect(Collectors.joining(" AND ", "(", ")")))
            .orElse(null);
}

Ensuite, vous obtenez null au lieu de () . p>


3 commentaires

… Un autre cas de «comment rendre mon code plus compliqué en insérant Facultatif . Comparer avec les filtres de retour == null || filters.isEmpty ()? null: fs.stream () .map (WorkListViewMapper :: formatValue) .map (f -> f.getCriteria () + f.getOperator () + f.getValue ()) .collect (Collectors.joining ("AND", "(", ")"));


@Holger selon le code en question, la sortie pour filters == null ne serait-elle pas () ? J'y ai d'abord pensé, mais c'est la raison pour laquelle je pense que la question est un peu compliquée.


@nullpointer, le comportement envisagé par l'OP n'est pas clair. L'exemple de code est conçu pour traiter null et la liste vide de la même manière, mais la question ne demande qu'un comportement particulier pour la liste vide. Vous pouvez l'interpréter d'une manière ou d'une autre. Mais mon commentaire précédent portait simplement sur le code de cette réponse, montrant comment réaliser la même chose plus simple sans un facultatif .