J'ai une instruction if avec beaucoup de conditions à l'intérieur, mais les conditions sont assez différentes. Cela a l'air vraiment volumineux. Je ne sais pas s'il existe un moyen de le faire.
// rqstCriteria is a List
// anotherCriteria is a List
// key# are the different values that I want to see if it has
if (
rqstCriteria.contains(key1) ||
rqstCriteria.contains(key2) ||
rqstCriteria.contains(key3) ||
rqstCriteria.contains(key4) ||
rqstCriteria.contains(key5) &&
(anotherCriteria != null &&
(anotherCriteria.contains(key1) ||
anotherCriteria.contains(key2) ||
anotherCriteria.contains(key3) ||
anotherCriteria.contains(key4) ||
anotherCriteria.contains(key5))
{...}
5 Réponses :
Commencez par rassembler toutes les clés dans la liste et en utilisant java-8 streams.anyMatch
if(list.stream().anyMatch(i->rqstCriteria.contains(i)) &&
Objects.nonNull(anotherCriteria) &&
list.stream().anyMatch(j->anotherCriteria.contains(j))) {
}
Et je dirais de déplacer le null code> vérifiez à l'extérieur de si bloquer, le meilleur moyen est de renvoyer une liste vide ou vous pouvez utiliser l'approche ci-dessous
List<String> list = List.of("key1","key2"); //or Arrays.asList()
if(list.stream().anyMatch(i->rqstCriteria.contains(i)) && list.stream().anyMatch(j->anotherCriteria.contains(j))) {
}
Vous pouvez écrire une méthode d'aide containsAny (merci à @chrylis pour l'optimiser):
if (containsAny(rqstCriteria, key1, key2, key3, key4, key5)
&& containsAny(anotherCriteria, key1, key2, key3, key4, key5)) {
...
}
Et ensuite l'utiliser dans vos instructions if: p >
public <T> boolean containsAny(Collection<T> c, T... keys) {
return c != null && Arrays.stream(keys).anyMatch(c::contains);
}
Arrays.stream (clés) serait beaucoup moins cher que de copier dans un HashSet .
@chrylis je suis tout à fait d'accord, merci
'' 'réponse courte et inutile' '' ': repensez votre modèle pour ne pas avoir besoin de plusieurs instructions if.
'' 'pas-si-long-mais-insightfull-and-pragmmatic-answer' ': Créez une hiérarchie de classes où chacune décrit une entité dont les propriétés seraient testées sur chaque cas If pertinent. p>
La classe Stuffy serait des objets qui remplissent, par définition, les conditions pour correspondre à if-1. Thingy serait la même chose à propos de if-2 ... Tous implémenteraient Anything ...
Ensuite, au lieu de votre grosse méthode doIt () avec un sale-laid if, chaque classe concrète implémenterait son propre doIt () (avec le code que vous mettriez sur chaque clause ifX).
Je pense que votre état est étrange. Mais
if (Stream.of(key1, key2, key3, key4).anyMatch(rqstCriteria::contains) ||
rqstCriteria.contains(key5) &&
anotherCriteria != null &&
Stream.of(key1, key2, key3, key4, key5).anyMatch(anotherCriteria::contains))
{}
Pour ajouter une autre approche utilisant des prédicats:
En supposant que vos listes de critères stockent des chaînes, créez un ensemble contenant vos clés:
if(containsOneOfMyKeys.test(rqstCriteria) &&
isNotNullOrEmpty.and(containsOneOfMyKeys).test(anotherCriteria)){
//do something
}
et deux prédicats qui acceptent une liste
Predicate<List<String>> containsOneOfMyKeys = l -> l.stream().anyMatch(s -> myKeys.contains(s)); Predicate<List<String>> isNotNullOrEmpty = l -> Objects.nonNull(l) && !l.isEmpty();
Ensuite, vous pouvez simplifier votre instruction if d'une manière lisible comme:
Set<String> myKeys = Set.of("key1","key2","key3","key4","key5");
Copie possible de Meilleur moyen de formater plusieurs Les conditions 'ou' dans une instruction if (Java) utilisent ceci pour chacune de vos listes, puis créent un arbre if plus petit
if (rqstCriteria.stream (). anyMatch (keySet :: contains)etc, oùkeySet = Set.of (key1, key2, ...).L'exemple semble étrange d'avoir
rqstCriteria.contains (key5) &&pas(rqstCriteria.contains (key1) ... rqstCriteria.contains (key5)) &&. Est-ce une faute de frappe ou une partie de la question - d'avoir ces vérifications exactement comme ça?