<String> 列出另一个列表忽略<String>大小写的子集?



>想象一下我有以下列表

列表a-("One", "Two", "Three", "Four", "Five")

列表b-("oNe", "two", "THREE")

我想b视为a的子集(忽略大小写(。

现在我正在使用循环和一些像这样的lambda。

boolean subset = true;                    
for(String bWord : b) {
if(!a.stream().anyMatch(aWord -> aWord.equalsIgnoreCase(bWord))) {
subset = false;
break;          
}
}

有没有更短的方法可以做到这一点,也许是 lambda?

将数组转换为小写:

a.stream().map(String::toLowerCase).collect(Collectors.toList());

并使用containsAll

b.containsAll(a);

您可以将a转换为小写Strings 的HashSet,这将使检查子集的速度更快(因为检查b的任何元素是否属于aset需要恒定的时间,而不是检查包含在List中所需的线性时间(:

Set<String> aset = a.stream().map(String::toLowerCase).collect(Collectors.toCollection(HashSet::new));
boolean subset = b.stream().map(String::toLowerCase).allMatch(aset::contains);

附言,您正在使用术语子集,但实际上您正在检查的不是List是否是另一个的子集,因为您的List不是Sets,这意味着它们可能包含重复的值。首先从Set开始会更有意义。

编辑:

如果使用containsAll对您来说似乎更好,请至少在两个Set而不是两个List上运行它。您将获得线性运行时间,而不是二次运行时间:

Set<String> aset = a.stream().map(String::toLowerCase).collect(Collectors.toCollection(HashSet::new));
Set<String> bset = b.stream().map(String::toLowerCase).collect(Collectors.toCollection(HashSet::new));
boolean subset = aset.containsAll(bset);

您可以使用不区分大小写的比较器创建 TreeSet 的子类

public class MyStringSet extends TreeSet<String> {
private static class CaseInsensiteStringComparator implements Comparator<String> {
@Override
public int compare(String a, String b) {
return a.toLowerCase().compareTo(b.toLowerCase());
}
}
public MyStringSet() {
super(new CaseInsensiteStringComparator());
}
public MyStringSet(Collection<? extends String> arg0) {
super(new CaseInsensiteStringComparator());
addAll(arg0);
}
public MyStringSet(Comparator<? super String> arg0) {
super(arg0);
}
public MyStringSet(SortedSet<String> arg0) {
super(new CaseInsensiteStringComparator());
addAll(arg0);
}
public static void main(String[] args) {
List<String> b = Arrays.asList("eins", "drei", "zwei");
MyStringSet a = new MyStringSet(Arrays.asList("Vier", "DRei", "zWei", "einS"));
System.out.println(a.containsAll(b));
}
}

相关内容

最新更新