Найти регулярное выражение в java arraylist
ArrayList <String> list = new ArrayList();
list.add("behold");
list.add("bend");
list.add("bet");
list.add("bear");
list.add("beat");
list.add("become");
list.add("begin");
Есть способ поиска regexp bea. * и получить индексы, как в ArrayList.indexOf?
EDIT: возврат элементов в порядке, но мне нужно что-то с большей производительностью, чем линейный поиск
Ответы
Ответ 1
Хермс правильно понял основы. Если вам нужны строки, а не индексы, то вы можете улучшить, используя цикл foreach Java 5:
import java.util.regex.Pattern;
import java.util.ListIterator;
import java.util.ArrayList;
/**
* Finds the index of all entries in the list that matches the regex
* @param list The list of strings to check
* @param regex The regular expression to use
* @return list containing the indexes of all matching entries
*/
List<String> getMatchingStrings(List<String> list, String regex) {
ArrayList<String> matches = new ArrayList<String>();
Pattern p = Pattern.compile(regex);
for (String s:list) {
if (p.matcher(s).matches()) {
matches.add(s);
}
}
return matches
}
Ответ 2
Есть ли встроенный метод? Не то, что я знаю из. Тем не менее, это должно быть довольно легко сделать это самостоятельно. Вот некоторый полностью непроверенный код, который должен дать вам основную идею:
import java.util.regex.Pattern;
import java.util.ListIterator;
import java.util.ArrayList;
/**
* Finds the index of all entries in the list that matches the regex
* @param list The list of strings to check
* @param regex The regular expression to use
* @return list containing the indexes of all matching entries
*/
List<Integer> getMatchingIndexes(List<String> list, String regex) {
ListIterator<String> li = list.listIterator();
List<Integer> indexes = new ArrayList<Integer>();
while(li.hasNext()) {
int i = li.nextIndex();
String next = li.next();
if(Pattern.matches(regex, next)) {
indexes.add(i);
}
}
return indexes;
}
Я мог бы неправильно использовать части Pattern и ListIterator (я тоже никогда не использовал), но это должно дать основную идею. Вы также можете сделать простой цикл for вместо цикла while над итератором.
Ответ 3
Одним из вариантов является использование метода "выбора" Apache Commons CollectionUtils. Вам нужно будет создать объект Predicate (объект с единственным методом "оценки", который использует регулярное выражение для проверки на совпадение и возвращает true или false), а затем вы можете искать элементы в списке, которые соответствуют. Однако он не возвращает индексы, он возвращает коллекцию, содержащую сами элементы.
Ответ 4
Это один лайнер в guava:
final Iterable<String> matches = Iterables.filter(myStrings, Predicates.contains(Pattern.compile("myPattern")));
for (final String matched : matches) {
...
}
Ответ 5
Я не верю, что есть способ Java API для этого, и нет способа сделать это Apache Commons. Это не составит труда сворачивать ваши собственные.
Ответ 6
Это возродит нить, но может быть кому-то полезно. Вам могут не понадобиться индексы, возможно, следующий шаг что-то сделает с элементами, которые соответствуют регулярному выражению, и поэтому вы запросили индексы. Но вы можете использовать потоки Java8 и лямбда-выражения:
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.List;
...
var pattern = Pattern.compile(define); // var is Java 10 feature
List<String> list = originalList
.stream()
.filter(e -> pattern.matcher(e).matches())
.collect(Collectors.toList());
Вы можете взять исходный список, преобразовать его в поток, запустить на нем фильтр, который запускает лямбду, чтобы соответствовать вашему шаблону, и преобразовать его обратно в список. Но вы можете сохранить его как поток и запустить .foreach на нем с другим лямбда-выражением.