web-dev-qa-db-fra.com

Quelle méthode de chaîne: "contient" ou "indexOf> -1"?

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("/")) 
43
sashank

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.


Éditer:

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.

90
Alex Lockwood

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

21
Ted M. Young

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.

4

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.

3
Pau Kiat Wee

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.

2
aleroot

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.

2
Alexander Kjäll

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)
1
Paul Jackson

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.

1
agcala