简体   繁体   English

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

[英]How do I check two collections for equality ignoring case?

I want to treat lowercase and uppercase values the same, and make sure two collections are equal (does not have to be sorted) 我想将小写和大写值相同,并确保两个集合相等(不必排序)

This is my implementation: 这是我的实现:

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

Is there an easier way to do this? 有没有更简单的方法可以做到这一点? Or is it better to have my own method 还是拥有自己的方法更好

Your actual solution is very acceptable. 您的实际解决方案是可以接受的。 It is clear enough and it should have a overall good performance. 很清楚,它应该具有总体良好的性能。

You should use Set.equals() instead of Set.containsAll() . 您应该使用Set.equals()而不是Set.containsAll() It makes the same things but it spare you from comparing the size as optimization. 它具有相同的作用,但是可以避免将大小作为优化进行比较。

1) A stream version of your code could be : 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) Here is a second alternative with Treeset . 2)这是Treeset的第二种选择。
I am not sure that it is easier but it avoids explicit loops and makes the logic more explicit as factored out : 我不确定是否更容易,但是它避免了显式循环,并且使逻辑变得更加明确:

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

Note that it removes duplicates according to the comparator. 请注意,它会根据比较器删除重复项。 That means that it sorts. 这意味着它可以排序。 So it could be slower or faster than your actual solution according to the cases. 因此,根据情况,它可能比您的实际解决方案慢或快。 Of course for small Set s to compare, it doesn't matter. 当然,要比较小的Set没关系。

Since there is no native library providing this, I think you'll always have to do some workaround, but the following could be an elegant solution without having to change your existing collections. 由于没有本机库提供此功能,因此我认为您总是必须采取一些变通方法,但是以下方法可能是一种优雅的解决方案,而无需更改您现有的馆藏。

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

Or even more easier to read 甚至更容易阅读

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

If an implementation that works with Set s is enough, you could store your unique elements in a TreeSet with a special case-insensitive comparator: 如果可以使用Set的实现就足够了,则可以使用不区分大小写的特殊比较器将唯一元素存储在TreeSet

Set<String> uniqueStrings = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);

This way you can make the comparison simply with uniqueStrings.equals(anotherTreeSet) . 这样,您可以简单地使用uniqueStrings.equals(anotherTreeSet)进行比较。 It's a bit of a hack, I have to admit. 我不得不承认,这有点骇人听闻。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用自定义相等函数检查两个集合是否相同(忽略顺序) - Check if two collections are the same (ignoring order) using a custom equality function 如何在JUnit中检查两个对象数组是否相等? - How can I check two Object-Arrays for Equality in JUnit? 如何比较Java摆动按钮图标以检查是否相等? - How do I compare java swing button icons to check equality? 如何测试两个电子邮件地址是否相等 - How do I test two email addresses for equality 如何在没有 equals 方法的情况下断言两个类的相等性? - How do I assert equality on two classes without an equals method? 检查两个列表以确保不区分大小写的交集? - Check two lists for intersection ignoring case-sensitive? 如何检查ArrayList中一个条目的一个字符串和一个字符串属性(在多个属性中)的相等性? - How do I check the equality of a String and one String-attribute (out of many) of an entry in an ArrayList? 我想将arrayList对象与String进行比较,忽略大小写。 我怎样才能做到这一点? - I want to compare an arrayList object with a String, ignoring case. How can I do this? 在java中检查两个字符串的相等性 - Check Equality of two Strings in java 如何检查字符串是否不等于多个其他字符串而忽略大小写 - How to check whether String is not equal to multiple other Strings ignoring case
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM