首页 > 解决方案 > 如何检查两个集合是否相等,忽略大小写?

问题描述

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

这是我的实现:

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

有没有更简单的方法来做到这一点?还是有自己的方法更好

标签: javacollections

解决方案


您的实际解决方案是非常可以接受的。已经够清晰了,应该有一个整体不错的表现。

您应该使用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);
}

请注意,它会根据比较器删除重复项。这意味着它排序。因此,根据具体情况,它可能比您的实际解决方案更慢或更快。当然对于小Sets来说比较无所谓。


推荐阅读