J'ai une méthode comme celle-ci
private boolean doValidGradoAntComp(final StringBuilder grade) { boolean isValid = false; switch (grade.toString()) { case "2o semester": isValid = true; break; case "4o semester": isValid = true; break; case "6o semester": isValid = true; break; case "8o semester": isValid = true; break; default: break; } return isValid; }
Et je veux la remplacer par quelque chose comme ceci:
private boolean validGrade(final StringBuilder grade) { boolean isValid = false; String semester = "semester"; if ((grade.toString().contains("2o") && grade.toString().contains(semester)) || (grade.toString().contains("4o") && grade.toString().contains(semester)) || (grade.toString().contains("6o") && grade.toString().contains(semester)) || (grade.toString().contains("8o") && grade.toString().contains(semester))) { isValid = true; } }
Et mon doute est: quel est le meilleur? Les deux fonctionnent de la même manière?
4 Réponses :
Non, les deux approches sont différentes. Dans la première approche, vous utilisez contains
pour vérifier que deux chaînes existaient dans grade
(par exemple 2o
et semestre
en grade
). Mais dans la deuxième approche, vous vérifiez que la note
est égale à 2o semestre
. Je préfère en rassembler tous pour lister et utiliser anyMatch
List<String> list = List.of("2o","4o","6o","8o"); if(list.stream().anyMatch(val->grade.contains(val) && grade.contains(semester))) {
Les deux servent le même objectif, mais chacun a ses différences, ses faiblesses et ses forces.
Si / sinon
Difficultés d'écriture et de lecture (le code est difficile à écrire car vous devez inclure des chèques à plusieurs valeurs dans une seule instruction)
Votre décision est de savoir si votre code sera exécuté ou non.
Comme pour le commutateur, vous pouvez créer une instruction default
si sa valeur n'est pas true (sinon).
Code facile à écrire et à lire. Vous entrerez toujours le bloc de commutation, s'il n'y a pas de cas qui correspond à la valeur que vous entrez, il sera par défaut. Vous ne pouvez utiliser Vous n'avez qu'une seule condition, contrairement à if / else vous pouvez avoir plusieurs types de conditions. Conclusion: Dans les problèmes de performances, le changement est généralement plus rapide mais les différences sont minimes. Si vous avez peu de cas à vérifier, j'utiliserais
char
ou int
que dans les cas. if / else
, mais dans votre cas, le code que vous avez montré est recommandé d'utiliser le switch case
pour le nombre de vérifie que vous le faites dans un seul bloc de code.
Pourquoi ne pas parcourir les possibilités?
private boolean validGrade(final StringBuilder grade) { return grade.toString().matches("[2468]o semester"); //exact match // return grade.toString().matches("[2468]o.*semester|semester.*[2468]o"); //loose match // return grade.toString().matches(".*([2468]o.*semester|semester.*[2468]o).*"); //equivalent to contains }
Sinon, si vous ne recherchez pas de correspondances exactes, faites:
private boolean validGrade(final StringBuilder grade) { String gradeString = grade.toString(); return gradeString.contains("semester") && List.of("2o", "4o", "6o", "8o") .stream() .anyMatch(gradeString::contains); }
Enfin, si votre ensemble de correspondances est inflexible ( sera toujours "2o", "4o", "6o", "8o"
), alors vous pouvez simplement utiliser une expression régulière:
private boolean validGrade(final StringBuilder grade) { String gradeString = grade.toString(); return List.of("2o", "4o", "6o", "8o") .stream() .map(x -> x + " semester") .collect(Collectors.toSet()) .contains(gradeString); }
p>
Je développerais l'expression régulière en . * (L'expression régulière actuelle). *
pour fournir une correspondance lâche car String.matches ()
ne renvoie vrai que si le toute la chaîne correspond. De cette façon, l'expression régulière correspondrait plus étroitement à la logique contains (...)
de la 1ère méthode. :)
@Thomas En fait, j'ai pensé à ça. Je ne savais pas si cela valait la peine de modifier la réponse après si longtemps, mais c'est certainement un bon point à garder dans les commentaires. En tout cas, c'est là maintenant.
Regex peut être plus lent que if-else ou switch. Mais dans votre cas, j'accorderais plus de valeur à la lisibilité et utiliserais regex.
private boolean validGrade(final StringBuilder grade) { return grade.toString().matches("(2o|4o|6o|8o) semester"); }
pensez-vous que les deux approches sont identiques?
contient
est différent et la casse du commutateur est différenteJe suggérerais de définir les valeurs en dehors du conditionnel (dans une variable booléenne distincte. Par exemple,
Boolean bool = grade.toString (). Contains (semester);
Eh bien, je dirais que la deuxième option est plus lisible et donc moins facile à se tromper. De plus, il n'appelle pas inutilement
grade.toString ()
plusieurs fois. Cependant, la première variante autorise plus de variantes que la seconde, c'est-à-dire que"quelque chose de semestre quel que soit 2o"
correspondrait àcontient ("2o")
etcontient ("semestre" )
également.Si toutes les variantes autorisées ressemblent à votre commutateur ci-dessus, vous pouvez également le faire en une seule ligne:
boolean isValid = grade.toString (). Matches ("[2468] o semester");
Que diriez-vous d'utiliser des
ensembles statiques ensembles
, qui contiennent ("2o", "4o", "8o" ...). Ensuite, utilisezsets.contains
pour effectuer le processus de jugement.