如何检查两个集合的相等性忽略大小写?

时间:2019-02-26 19:43:11

标签: java collections

我想将小写和大写值相同,并确保两个集合相等(不必排序)

这是我的实现:

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);
}

有更简单的方法吗?或者拥有自己的方法更好

3 个答案:

答案 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)进行比较。我不得不承认,这有点骇人听闻。