我想将小写和大写值相同,并确保两个集合相等(不必排序)
这是我的实现:
private boolean stringCollectionEqualsIgnoreCase(Collection<String> c1, Collection<String> c2)
{
Set<String> s1 = new HashSet<>();
c1.forEach(i -> s1.add(i.toLowerCase()));
Set<String> s2 = new HashSet<>();
c2.forEach(i -> s2.add(i.toLowerCase()));
return s1.size() == s2.size() && s2.containsAll(s1);
}
有更简单的方法吗?或者拥有自己的方法更好
答案 0 :(得分:2)
您的实际解决方案是可以接受的。很清楚,它应该具有总体良好的性能。
您应该使用Set.equals()
而不是Set.containsAll()
。它具有相同的作用,但是可以避免将大小作为优化进行比较。
1)您的代码的流版本可能是:
private boolean stringCollectionEqualsIgnoreCase(Collection<String> c1, Collection<String> c2) {
return c1.stream()
.map(String::toLowerCase)
.collect(toSet())
.equals(c2.stream()
.map(String::toLowerCase)
.collect(toSet()));
}
2)这是Treeset
的第二种选择。
我不确定是否更容易,但是它避免了显式循环,并且使逻辑变得更加明确:
private boolean stringCollectionEqualsIgnoreCase(Collection<String> c1, Collection<String> c2)
{
Comparator<String> comp = Comparator.comparing(String::toLowerCase);
Set<String> s1 = new TreeSet<>(comp);
Set<String> s2 = new TreeSet<>(comp);
s1.addAll(c1);
s2.addAll(c2);
return s1.equals(s2);
}
请注意,它会根据比较器删除重复项。这意味着它可以排序。因此,根据情况,它可能比您的实际解决方案慢或快。当然,要比较小的Set
,没关系。
答案 1 :(得分:0)
由于没有本机库提供此功能,所以我认为您总是必须做一些变通方法,但是以下可能是一种优雅的解决方案,而不必更改您现有的馆藏。
public boolean containsAllIgnoreCase(Collection<String> var1, Collection<String> var2) {
return var1.stream()
.map(String::toLowerCase)
.collect(toList())
.containsAll(var2.stream()
.map(String::toLowerCase)
.collect(toList());
}
或更容易阅读
public List<String> toLowerCaseList(Collection<String> var) {
return var.stream().map(String::toLowerCase).toList();
}
public boolean containsAllIgnoreCase(Collection<String> var1, Collection<String> var2) {
return toLowerCaseList(var1).containsAll(toLowerCaseList(var2));
}
答案 2 :(得分:0)
如果可以使用Set
的实现就足够了,则可以使用不区分大小写的特殊比较器将唯一元素存储在TreeSet
中:
Set<String> uniqueStrings = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
这样,您可以简单地与uniqueStrings.equals(anotherTreeSet)
进行比较。我不得不承认,这有点骇人听闻。