Какой из следующих способов является эффективным способом определения сдерживания подстроки?
if (str.indexOf("/") > -1)
или
if (str.contains("/"))
Какой из следующих способов является эффективным способом определения сдерживания подстроки?
if (str.indexOf("/") > -1)
или
if (str.contains("/"))
Взгляните на исходный код java.lang.String
. Метод contains
реализуется с помощью вызова indexOf
, поэтому они по существу одинаковы.
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
Вы должны использовать тот способ, который делает ваш код более читаемым. Если вы проверяете, содержит ли String определенную подстроку, используйте contains
. Если вы ищете индекс начала подстроки, используйте indexOf
.
В нескольких ответах упоминается, что indexOf
должен быть предпочтительнее contains
из-за того, что contains
вызывает дополнительный вызов метода и, следовательно, менее эффективен. Это неправильно. Накладные расходы, вызванные дополнительным вызовом метода в этом случае, совершенно незначителен. Используйте тот метод, который имеет наибольший смысл в контексте вашей реализации. Это сделает ваш код более удобочитаемым.
Я подумал, что я бы использовал эмпирический подход к этому вопросу, вместо того, чтобы гадать, как накладные расходы при вызове дополнительного метода повлияют на результат. Я взял indexOf
из этого ответа и добавил два метода тестовых методов для функции contains()
(один принимает строковую константу, а другой - переменную). Я использую только что вышедшую 1.8.0_71 под управлением 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
Обратите внимание, что эталонные измерения составляют наносекунды за операцию. Таким образом, сравнение содержит ("z") и indexOf ("z"), indexOf() очень немного быстрее, но менее чем на 0,6 нс. Интересно, что косвенный (с использованием переменной) имеет большую разницу чуть более 1 нс.
Я разместил код для этого теста на GitHub: https://github.com/tedyoung/indexof-contains-benchmark
В принципе оба одинаковы,
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
Но если вы хотите что-то сделать с помощью индекса, вы можете использовать indexOf
.
Я считаю, что indexOf
будет более эффективным, но разницу можно игнорировать.
Если цель состоит в том, чтобы определить, содержит ли одна String другую, то contains()
является явным победителем. Это сделает других разработчиков более эффективными в понимании ваших намерений.
Методы имеют различное применение, если вам нужно проверить, содержит ли String что-то, а затем использовать их, но если вы хотите знать, где в конечном итоге содержится строка, используйте метод indexOf.
При использовании str.contains("/")
явно более читабельна, вероятно, более эффективно использовать str.indexOf('/') > -1
. Обратите внимание, что я использую символ вместо строки в вызове indexOf.
Но это не должно иметь большого значения, если вы находитесь в очень узкой петле.
Недавно у меня возникла эта проблема с помощью indexOf()
: при попытке найти , если строка содержит пробелы, чтобы заменить их чем-то другим, ответ от IndexOf был: Строка не имела пробелы, что было неправильным ответом. При замене на Contains()
ответ был правильным. Перейдите на фигуру, потому что, как некоторые из них сказали, Contains()
отправляет вызов IndexOf
.
Для одиночных поисковых запросов, таких как ваш пример, indexOf более эффективен , если аргумент indexOf является char:
if (str.indexOf('/') > -1)
В эти дни содержимое не будет работать. Вместо этого использование включает в себя, например,
yourString.includes( 'SearchString')
Смотрите этот ответ: fooobar.com/info/693176/...