![](/img/trans.png)
[英]check if an ArrayList contains all Strings from another ArrayList
[英]How to check if an ArrayList of Strings contains substrings of another ArrayList of Strings?
List<String> actualList = Arrays.asList ("mother has chocolate", "father has dog");
List<String> expectedList = Arrays.asList ("mother", "father", "son", "daughter");
有沒有辦法檢查expectedList
包含actualList
字符串的任何子字符串?
我找到了一個嵌套的for-each解決方案:
public static boolean hasAny(List<String> actualList, List<String> expectedList) {
for (String expected: expectedList)
for (String actual: actualList)
if (actual.contains(expected))
return true;
return false;
}
我試圖尋找lambda解決方案,但我不能。 我找到的所有方法都檢查String#equals
而不是String#contains
。
有這樣的東西會很高興:
CollectionsUtils.containsAny(actualList, exptectedList);
但它使用String#equals
而不是String#contains
來比較字符串。
編輯:
基於問題:如果來自actualList的所有subStrings都是expectedList的一部分,我想得到TRUE。 以下凱文的解決方案適合我。
這樣的事情怎么樣:
list1.stream().allMatch(s1 -> list2.stream().anyMatch(s2 -> s1.contains(s2)))
allMatch
將檢查一切是否true
anyMatch
將檢查至少有一個是否為true
這里有類似Java 7風格的東西,沒有lambdas和流,可以更好地理解發生的事情:
boolean allMatch = true; // Start allMatch at true
for(String s1 : list1){
boolean anyMatch = false; // Start anyMatch at false inside the loop
for(String s2 : list2){
anyMatch = s1.contains(s2);// If any contains is true, anyMatch becomes true as well
if(anyMatch) // And stop the inner loop as soon as we've found a match
break;
}
allMatch = anyMatch; // If any anyMatch is false, allMatch becomes false as well
if(!allMatch) // And stop the outer loop as soon as we've found a mismatch
break;
}
return allMatch;
如果您希望擁有CollectionsUtils.containsAny(list1, list2)
您可以在代碼中的其他地方重用,您可以自己創建一個:
public final class CollectionsUtil{
public static boolean containsAny(ArrayList<String> list1, ArrayList<String> list2){
return list1.stream().allMatch(s1 -> list2.stream().anyMatch(s2 -> s1.contains(s2)));
// Or the contents of the Java 7 check-method above if you prefer it
}
private CollectionsUtil(){
// Util class, so it's not initializable
}
}
然后可以根據需要使用它:
boolean result = CollectionsUtils.containsAny(actualList, expectedList);
我99%肯定你是不是在找hasAny
喜歡這里的大多數upvoted答案,而是要看看是否全部來自expectedList
都包含在所有的字符串actualList
。 為此,首先創建一個Set
和work的工作是有益的(因為對於HashSet
contains
O(1)
並且對於List
與O(n)
相對)。
現在考慮一下,因為你想要的只是contains
,你可以分割那個actualList
並從中創建唯一的單詞:
private static boolean test(List<String> actualList, List<String> expectedList) {
Pattern p = Pattern.compile("\\s+");
Set<String> set = actualList.stream()
.flatMap(p::splitAsStream)
.collect(Collectors.toSet());
return expectedList.stream().allMatch(set::contains);
}
public static boolean containsAny(List<String> actualList, List<String> expectedList) {
final Pattern words = Pattern.compile("\\s+");
return actualList.stream()
.flatMap(words::splitAsStream)
.distinct()
// .allMatch(expectedList::contains)
.anyMatch(expectedList::contains);
}
Kevin的答案更好,但另一種方法是覆蓋Wrapper對象的equals方法。
import org.springframework.util.CollectionUtils;
class Holder {
public String obj;
public Holder(String obj) {
this.obj = obj;
}
@Override
public boolean equals(Object holder) {
if (!(holder instanceof Holder))
return false;
Holder newH = ((Holder) holder);
if (newH == null || newH.obj == null || obj == null)
return false;
return obj.contains(newH.obj) || newH.obj.contains(obj); //actually it's should be one directed.
}
}
CollectionUtils.containsAny(
actual.stream().map(Holder::new).collect(Collectors.toList()),
expected.stream().map(Holder::new).collect(Collectors.toList())
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.