Java Set equality ignore case

前端 未结 6 1465
渐次进展
渐次进展 2020-12-11 00:14

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

Set set1 ;
Set set2 ;
.
.
.
if(s         


        
相关标签:
6条回答
  • 2020-12-11 00:25

    Not that I know of.

    The best solution I can see, albeit over-engineered, would be to create your custom holder class holding a String instance field (String is final and cannot be inherited).

    You can then override equals / hashCode wherein for two String properties equalsIgnoreCase across two instances, equals would return trueand hashCodes would be equal.

    This implies:

    • hashCode returns a hash code based on a lower (or upper) cased property's hash code.
    • equals is 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));
       }
      

    Output

    true
    

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

    0 讨论(0)
  • 2020-12-11 00:34

    You can use a loop and equalsIgnoreCase

    testString.equalsIgnoreCase()
    
    0 讨论(0)
  • 2020-12-11 00:35

    Alternatively you can use 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));
    }
    
    0 讨论(0)
  • 2020-12-11 00:35

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

    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;
    }
    
    0 讨论(0)
  • 2020-12-11 00:43

    Unfortunately, Java does not let you supply an external "equality comparer": when you use strings, HashSet uses only built-in hashCode and equals.

    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:

    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
    }
    
    0 讨论(0)
  • 2020-12-11 00:45

    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;
    }
    
    0 讨论(0)
提交回复
热议问题