#java #if-statement #for-loop #performance
#java #if-оператор #для цикла #Производительность
Вопрос:
Давайте просто скажем, что вам нужно отредактировать ряд слов из arraylist («cat», «dog», «catdog», «mandog»)
Теперь вы можете либо поместить это в цикл for, вот так
for(int i=0; i<arraylist.size(); i ){
if(arraylist.get(i).matches("cat") || arraylist.get(i).matches("dog") etc.. etc..
{
//do something
}
}
Или вы можете поместить слова (cat, dog, catdog и mandog) в массив строк / arraylist и сравнить их, используя это.
Какой из них более эффективен?
Принимая во внимание, что список слов может быть довольно большим.
Спасибо за помощь.
Комментарии:
1. Более эффективным является извлечение
arrayList.get(i)
операции из if, чтобы она оценивалась только один раз.2. Я сомневаюсь, что это будет иметь такое большое значение. Здесь более важна удобочитаемость кода: вам не нужен гигантский оператор if, который явно сравнивает .get(i) с каждым словом
3. Ни то, ни другое. Поместите слова в набор и посмотрите, есть ли
arraylist.get(i)
в наборе.4. Кроме того, использовать
matches()
, когда на самом деле регулярное выражение не используется, тоже не самое мудрое, что можно сделать.5. Какой тип операции вы хотите выполнить с этими строками ?
Ответ №1:
Ни то, ни другое, разница в производительности будет незначительной, оба они линейны по времени в размере списка ключевых слов.
Учитывая, что список слов может стать довольно большим, вам следует использовать Set
. HashSet
Может выполнять contains
проверку в постоянное время, что делает его очень подходящим для этой цели. Итак:
Set<String> keywords = new HashSet<>();
keywords.add("cat");
keywords.add("dog");
// ...
for (String element: arraylist) {
if (keywords.contains(element)) {
// Do something
}
}
Обратите внимание, что использование matches
так, как вы делаете, на самом деле такое же, как использование equals
, поэтому мы можем просто проверить на равенство.
Комментарии:
1. HashSet — это лучший способ проверить, содержит элемент или нет, и это делается в постоянное время. Обратите внимание, что метод contains чувствителен к регистру, и он не будет работать, если вы хотите сравнить со строкой «Cat» из данного примера кода, тогда рекомендуется добавить ключевое слово в нижнем регистре и сравнивать только в режиме нижнего регистра, например.
Ответ №2:
Я думаю, что подходящий способ (хотя и намного больше работы) — протестировать все варианты. Используйте профилировщик, чтобы увидеть, сколько времени требуется вашему коду для выполнения поиска, а затем перейдите к процессу, который дает наилучшие результаты.
Без использования профилировщика очень сложно определить улучшения в производительности.
Комментарии:
1. Не всегда. Если вы можете заменить структуру данных другой в более сложном по времени классе для необходимых вам операций (например, HashSet против ArrayList для сдерживания), вы почти наверняка внесете улучшение производительности.
2. @StefanoSanfilippo Да, вы правы. Это также отличный способ обеспечить повышение производительности кода. Однако вам все равно было бы трудно объективно определить, какие изменения улучшили код, без какого-либо способа его измерения.
Ответ №3:
Поскольку вы используете matches()
метод в своем коде, я предполагаю, что вам нужно выполнить сопоставление с регулярным выражением. Если это так, вы могли бы использовать вложенный цикл for.
String[] patterns = {"cat", "dog"};
for(String item : arraylist){
for(String pattern : patterns){
if(item.matches(pattern)){
//do something
}
}
}
Если вы просто хотите проверить, присутствует ли строка в списке, вы могли бы использовать подход Стефано Санфилиппо.
Комментарии:
1. Нет необходимости оборачивать
patterns
массив в список, вы также можете выполнять итерации по массивам.2. ДА. Извините, это был просто мой обычный стиль кодирования.. Отредактировано .. 🙂
3. Если и список массивов, и группа шаблонов содержат много записей, вы можете объединить шаблоны программно (используя скобки и
|
) в один шаблон, скомпилировать его один раз, а затем сопоставить со всеми элементами списка массивов. Но, похоже, «совпадения» на самом деле не были необходимы.