Java Set<String> 相等忽略大小写

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24558456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 12:59:46  来源:igfitidea点击:

Java Set<String> equality ignore case

javasetignore-case

提问by nafas

I want to check if all elements of two sets of String are equal by ignoring the letter's cases.

我想通过忽略字母的大小写来检查两组 String 的所有元素是否相等。

Set<String> set1 ;
Set<String> set2 ;
.
.
.
if(set1.equals(set2)){ //all elements of set1 are equal to set2 
 //dosomething
}
else{
 //do something else
}

However, this equality check doesn't ignore the cases of the string. Is there some other way of doing that?

但是,此相等性检查不会忽略字符串的大小写。有没有其他方法可以做到这一点?

采纳答案by Syam S

Alternatively you can use TreeSet.

或者,您可以使用TreeSet.

public static void main(String[] args){
    Set<String> s1 = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
    s1.addAll(Arrays.asList(new String[] {"a", "b", "c"}));

    Set<String> s2 = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
    s2.addAll(Arrays.asList(new String[] {"A", "B", "C"}));

    System.out.println(s1.equals(s2));
}

回答by Othya

You can use a loop and equalsIgnoreCase

您可以使用循环和 equalsIgnoreCase

testString.equalsIgnoreCase()

回答by Mena

Not that I know of.

从来没听说过。

The best solution I can see, albeit over-engineered, would be to create your custom holder class holding a Stringinstance field (Stringis finaland cannot be inherited).

我能看到的最佳解决方案,尽管过度设计,是创建您的自定义持有者类,其中包含一个String实例字段(Stringfinal和不能被继承)。

You can then override equals/ hashCodewherein for two Stringproperties equalsIgnoreCaseacross two instances, equalswould return trueand hashCodes would be equal.

然后,您可以覆盖equals/ where跨两个实例的hashCode两个String属性equalsIgnoreCaseequals将返回true并且hashCodes 将相等。

This implies:

这意味着:

  • hashCodereturns a hash code based on a lower (or upper) cased property's hash code.
  • equalsis based on equalsIgnoreCase

    class MyString {
        String s;
    
        MyString(String s) {
            this.s = s;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((s == null) ? 0 : s.toLowerCase().hashCode());
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            MyString other = (MyString) obj;
            if (s == null) {
                if (other.s != null)
                    return false;
            }
            else if (!s.equalsIgnoreCase(other.s))
                return false;
            return true;
        }
    
    }
    public static void main(String[] args) {
            Set<MyString> set0 = new HashSet<MyString>(
                Arrays.asList(new MyString[]
                    {
                        new MyString("FOO"), new MyString("BAR")
                    }
                )
            );
            Set<MyString> set1 = new HashSet<MyString>(
                Arrays.asList(new MyString[]
                    {
                        new MyString("foo"), new MyString("bar")
                    }
                )
            );
            System.out.println(set0.equals(set1));
     }
    
  • hashCode返回基于小写(或大写)属性的哈希码的哈希码。
  • equals是基于 equalsIgnoreCase

    class MyString {
        String s;
    
        MyString(String s) {
            this.s = s;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((s == null) ? 0 : s.toLowerCase().hashCode());
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            MyString other = (MyString) obj;
            if (s == null) {
                if (other.s != null)
                    return false;
            }
            else if (!s.equalsIgnoreCase(other.s))
                return false;
            return true;
        }
    
    }
    public static void main(String[] args) {
            Set<MyString> set0 = new HashSet<MyString>(
                Arrays.asList(new MyString[]
                    {
                        new MyString("FOO"), new MyString("BAR")
                    }
                )
            );
            Set<MyString> set1 = new HashSet<MyString>(
                Arrays.asList(new MyString[]
                    {
                        new MyString("foo"), new MyString("bar")
                    }
                )
            );
            System.out.println(set0.equals(set1));
     }
    

Output

输出

true

... as said, over-engineered (but working).

... 如前所述,过度设计(但有效)。

回答by dasblinkenlight

Unfortunately, Java does not let you supply an external "equality comparer": when you use strings, HashSetuses only built-in hashCodeand equals.

不幸的是,Java 不允许您提供外部“相等比较器”:当您使用字符串时,HashSet只使用内置的hashCodeequals.

You can work around this problem by populating an auxiliary HashSet<String>with strings converted to a specific (i.e. upper or lower) case, and then checking the equality on it, like this:

您可以通过HashSet<String>使用转换为特定(即大写或小写)大小写的字符串填充辅助字符串来解决此问题,然后检查它的相等性,如下所示:

boolean eq = set1.size() == set2.size();
if (eq) {
    Set<String> aux = new HashSet<String>();
    for (String s : set1) {
        aux.add(s.toUpperCase());
    }
    for (String s : set2) {
        if (!aux.contains(s.toUpperCase())) {
            eq = false;
            break;
        }
    }
}
if (eq) {
    // The sets are equal ignoring the case
}

回答by spa

I would build something like this (in some form of Java pseudo code):

我会构建这样的东西(以某种形式的 Java 伪代码):

Set<String> set1;
Set<String> set2;

if (set1.size() != set2.size()) {
  return NOT_EQUAL;
} else {
  Set<String> set3 = new HashSet<String>();
  for (String s: set1) set3.add(s.toUpperCase());
  for (String s: set2) set3.add(s.toUpperCase());
  return set1.size() == set3.size() ? EQUAL : NOT_EQUAL;
}

回答by Jim Garrison

Untested, but this is the general idea:

未经测试,但这是一般的想法:

public boolean setEqualsIgnoreCase(Set<String> a, Set<String>b)
{
    if (a.size() != b.size()) return false;
    Iterator<String> ai = a.iterator();
    Iterator<String> bi = b.iterator();
    while(ai.hasNext())
    {
         if (!ai.next().equalsIgnoreCase(bi.next())) return false;
    }
    return true;
}