Java Lambda - поиск, если какой-либо элемент списка String частично совпадает с любым элементом другого списка
У меня есть 2 списка String
A = {"apple", "mango", "pineapple", "banana", ... }
B = {"app", "framework",...}
Что я ищу, так это: любой элемент B хотя бы частичное совпадение (substring/contains/startsWith
) с любым элементом A. например, 1-й элемент B 'app' частично совпадает хотя бы с одним элементом 'apple'.
Другие близко совпадающие темы в Stackru не учитывают 2 списка.
Есть ли какой-нибудь элегантный способ выразить решение с помощью Java лямбда?
Я чувствую, что это общая проблема в области поиска. Так что, если есть какая-либо помощь или интересное чтение по этой теме, я был бы рад получить указатели.
2 ответа
Зависит от того, что вы подразумеваете под элегантным, но попробуйте это:
List<String> r = list1
.parallelStream()
.filter( w1->{
return list2
.parallelStream()
.anyMatch( w2->w1.contains(w2) );
}
)
.collect(Collectors.toList());
anyMatch
(а также filter
) может быть закорочена и прервет поток второго списка после нахождения первого совпадения w1.contains(w2)
и верните true, если найдено, давая некоторую эффективность. Используйте это, чтобы отфильтровать первый поток. Делайте это в параллельных потоках.
Вы могли бы связать потоки двух List<String>
и фильтровать с String.contains()
или любое другое условие, которое вы хотите использовать (substring()
, startsWith()
)
Затем вы можете отобразить пару строк, которые соответствуют условию в String
массив:
List<String> listOne = Arrays.asList("apple", "mango", "pineapple", "framework");
List<String> listTwo = Arrays.asList("app", "frame");
List<String[]> values = listOne.stream()
.flatMap(x -> listTwo.stream()
.filter(y -> x.contains(y))
.map(y -> {
return new String[] { x, y };
}))
.collect(Collectors.toList());
for (String[] array : values) {
System.out.println(Arrays.toString(array));
}
Выход:
[яблоко, приложение]
[ананас, приложение]
[рамки, рамки]