2
votes

Java compare les valeurs, meilleur moyen

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?


5 commentaires

pensez-vous que les deux approches sont identiques? contient est différent et la casse du commutateur est différente


Je 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") et contient ("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, utilisez sets.contains pour effectuer le processus de jugement.


4 Réponses :


2
votes

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))) {


0 commentaires

1
votes

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 char ou int que dans les cas.

  • 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 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.


0 commentaires

2
votes

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>


2 commentaires

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.



1
votes

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");
}


0 commentaires