Lequel des moyens suivants est un moyen efficace de déterminer le confinement de la sous-chaîne?
if (str.indexOf("/") > -1)
ou
if (str.contains("/"))
Jetez un oeil à la Java.lang.String
code source. La méthode contains
est implémentée à l'aide d'un appel à indexOf
, elles sont donc essentiellement les mêmes.
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
Vous devez utiliser la méthode qui rend votre code plus lisible. Si vous vérifiez si une chaîne contient une sous-chaîne spécifique, utilisez contains
. Si vous recherchez l'index de départ de la sous-chaîne, utilisez indexOf
.
Quelques réponses mentionnent que indexOf
devrait être préféré à contains
en raison du fait que contains
effectue un appel de méthode supplémentaire et est donc moins efficace. C'est faux. La surcharge causée par un appel de méthode supplémentaire dans ce cas est totalement insignifiante. Utilisez la méthode la plus appropriée dans le contexte de votre implémentation. Cela rendra votre code plus lisible.
J'ai pensé adopter une approche empirique à cette question, au lieu de deviner comment la surcharge de l'appel de méthode supplémentaire affecterait le résultat. J'ai pris le benchmark indexOf
de cette réponse , et ajouté deux méthodes de benchmark pour contains()
(une qui prend une constante de chaîne et une autre qui prend une variable). J'utilise le 1.8.0_71 qui vient de sortir sous Windows x64.
# JMH 1.11.3 (released 8 days ago)
# VM version: JDK 1.8.0_71, VM 25.71-b15
Benchmark Mode Cnt Score Error Units
IndexOfTest.containsString avgt 30 26.596 ± 0.099 ns/op
IndexOfTest.containsStringIndirect avgt 30 28.683 ± 0.088 ns/op
IndexOfTest.indexOfChar avgt 30 26.855 ± 0.171 ns/op
IndexOfTest.indexOfCharIndirect avgt 30 25.833 ± 0.116 ns/op
IndexOfTest.indexOfString avgt 30 26.192 ± 0.107 ns/op
IndexOfTest.indexOfStringIndirect avgt 30 27.547 ± 0.152 ns/op
Notez que les mesures de référence sont des nanosecondes par opération. Ainsi, la comparaison contient ("z") et indexOf ("z"), indexOf () est très légèrement plus rapide, mais de moins de 0,6 ns. Chose intéressante, l'indirect (en utilisant la variable) présente une différence plus importante d'un peu plus de 1 ns.
J'ai placé le code de cette référence sur GitHub: https://github.com/tedyoung/indexof-contains-benchmark
Si le but est de déterminer si une chaîne en contient une autre, alors contains()
est clairement le gagnant. Cela rendra les autres développeurs plus efficaces dans la compréhension de votre intention.
Fondamentalement, les deux sont identiques,
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
Mais si vous voulez faire quelque chose via l'index, vous pouvez utiliser indexOf
.
Je pense que indexOf
sera plus efficace, mais la différence peut être ignorée.
Les méthodes ont une utilisation différente, si vous devez vérifier si la chaîne contient quelque chose, utilisez le contient, mais si vous voulez savoir où dans la chaîne il est éventuellement contenu, utilisez la méthode indexOf.
Bien que l'utilisation de str.contains("/")
soit clairement plus lisible, il est probablement plus efficace d'utiliser str.indexOf('/') > -1
. Notez que j'utilise un caractère au lieu d'une chaîne dans l'appel indexOf.
Mais cela ne devrait pas vraiment avoir d'importance en termes de performances, sauf si vous êtes dans une boucle très serrée.
Pour les recherches à caractère unique telles que votre exemple, indexOf est plus efficace si l'argument à indexOf est un caractère:
if (str.indexOf('/') > -1)
Récemment, j'ai eu ce problème en utilisant indexOf()
: lorsque j'essayais de trouver si une chaîne contenait des espaces pour les remplacer par autre chose, la réponse d'IndexOf était: la chaîne n'avait pas d'espace, ce qui était une mauvaise réponse. Lorsqu'il est remplacé par Contains()
la réponse était la bonne. Allez comprendre, car comme certains l'ont dit ici, Contains()
publie un appel à IndexOf
.