代码之家  ›  专栏  ›  技术社区  ›  Isabel Jinson

使用集合比较字符串数组

  •  4
  • Isabel Jinson  · 技术社区  · 15 年前

    我有两个字符串数组a,b。

    String a [] = {"one","two","three"};
    String b [] = {"one","Two","Three","four"};
    

    我需要检查两个数组是否相同,不区分大小写。 我知道,下面这段代码非常适合区分大小写。

    List <String> l1 = Arrays.asList(a);
    List <String> l2 = Arrays.asList(b);
    System.out.println(l2.containsAll(l1));  
    

    有没有其他方法可以使用collection比较两个字符串数组(不区分大小写)?

    8 回复  |  直到 15 年前
        1
  •  4
  •   Isabel Jinson    15 年前

    最后,我使用treeset和不区分大小写的比较器。

    例子:

     String [] oldVal = {"one","two","three","Four"};
     String [] newVal = {"one","Two","Three","four"};
    
     Set <String> set1 = new TreeSet <String> (String.CASE_INSENSITIVE_ORDER);
     Set <String> set2 = new TreeSet <String> (String.CASE_INSENSITIVE_ORDER);
    
     set1.addAll(Arrays.asList(oldVal));
     set2.addAll(Arrays.asList(newVal));
    
     System.out.println("--Using Tree Set --- "+ set1.containsAll(set2));  // Return True
    

    谢谢你们..

        2
  •  1
  •   JonH    15 年前

    你就不能循环一下或者用某种LINQ (抱歉刚才注意到这是Java,你不能使用LINQ……)

        List<string> matches = new List<string>();
        bool isSame=true;
    
        foreach(string s1 in l1)
         {
          foreach(string s2 in l2)
            {
             if(s1.ToLower() == s2.ToLower()) 
              matches.Add(s1);
             else
                {
                 isSame=false;
                 break;
                }
            }
           if (isSame) 
                continue;           
           else
                break;
         }
    
    if (isSame)
        Console.Writeline("They are the same")
    else
        Console.Writeline("Not the same");
    

    您可能需要检查计数,因为我没有将其添加到代码中,例如l1.count>l2.count(在这种情况下,您可以通过列表中元素的数量知道它们是否相同)。循环之前的简单测试:

    if (l1.Count != l2.Count) {
     //don't even bother looping
     //display no matches
    }
    else {
     //place rest of code here since l1.count = l2.count
    }
    
    • 克拉普没有意识到这是因为Java认为是C语言。应用 但是Java的逻辑是相同的…
        3
  •  1
  •   JRL    15 年前

    你可以用一个 TreeMap 使用不区分大小写的比较器。

        4
  •  1
  •   polygenelubricants    15 年前

    如果数组不包含重复项 ,一种方法 O(N) 是使用 Set 表示数组中字符串的规范形式。像这样的:

    static Set<String> canonicalSet(String[] arr) {
        Set<String> upperSet = new HashSet<String>();
        for (String s : arr) {
            upperSet.add(s.toUpperCase());
        }
        return upperSet;
    }
    static boolean equalsCanonically(String[] arr1, String[] arr2) {
        return canonicalSet(arr1).equals(canonicalSet(arr2));
    }
    

    这是最佳时间。

    您还可以对该技术进行更改以节省更多空间,例如,您可以为 arr1 ,然后根据 arr2 . 如果之后集合是空的,并且您总是可以找到需要删除的内容,那么这两个数组在规范上是相等的。

    static boolean equalsCanonically2(String[] arr1, String[] arr2) {
        Set<String> canon = canonicalSet(arr1);
        for (String s : arr2) {
            if (!canon.remove(s.toUpperCase())) return false;
        }
        return canon.isEmpty();
    }
    

    如果你觉得值得的话,你也可以做一个简单的大小比较检查(也就是说,如果两个数组的元素数量不一样的话)。

    如果数组中有重复项,则 集合 方法不会按原样工作。你需要一个multiset,你可以实现自己的,也可以使用google collections。


    还有 O(N log N) 方法包括对字符串进行排序。可以对两个数组进行排序,然后进行简单的线性检查。必须使用不区分大小写的比较器,事实上它已经作为 String.CASE_INSENSITIVE_ORDER .

    static boolean equalsCanonically3(String[] arr1, String[] arr2) {
        int N = arr1.length;
        if (arr2.length != N) return false;
        Arrays.sort(arr1, String.CASE_INSENSITIVE_ORDER);
        Arrays.sort(arr2, String.CASE_INSENSITIVE_ORDER);
        for (int i = 0; i < N; i++) {
            if (String.CASE_INSENSITIVE_ORDER.compare(arr1[i], arr2[i]) != 0) {
                return false;
            }
        }
        return true;
    }
    

    即使数组包含重复项,最后一种技术也可以工作。它做到了 O(n log n) . 它对作为参数传递的数组进行排序,因此如果原始状态很重要,则需要传递 clone() 相反。

        5
  •  0
  •   Andrey    15 年前

    如果需要自定义比较,请在嵌套循环中选中它。或者如果您有大量的数据集,那么首先对数组排序可能会更便宜

        6
  •  0
  •   CPerkins    15 年前

    样本数据已排序。如果这在现实中是肯定的,那么您应该按照andrey所说的那样做,并在数组本身上使用嵌套循环,当您发现一对不相等的条目时,中断if/when。

    如果它们不保证被排序,我会把它们中的每一个转储到一个哈希集中,然后你就可以使用Java的StaseCubsAsALL方法。

    编辑:正如Thomman指出的,containsAll()最终依赖于equals()。因此,为了让不区分大小写的人检查您的问题请求,您有两个选择:

    1)将字符串插入到集合中时,将字符串上移或下移。考虑到这一点,我不喜欢这种方法,因为不仅会丢失重复的条目,而且还会按大小写对条目进行折叠。所以这些列表看起来是相等的:

    
    String a [] = {"one","one","one", "Two"};
    String b [] = {"One", Two"};
    

    2)另一种选择是将字符串放入重写equals()的holder对象中,以不区分大小写的方式进行比较。

        7
  •  0
  •   fastcodejava    15 年前

    你可以先看看它们的长度是否相等。然后你可以把 a 在里面 HashMap 然后过去 b 并检查物品是否在那里。

        8
  •  0
  •   Isabel Jinson    15 年前

    使用一个for循环-

    String [] oldVal = {"one","two","three","Four"};
    String [] newVal = {"one","Two","Three","four"};
    
    
    if(oldVal.length == newVal.length)
    {
     //
     for(int y =0; y<oldVal.length; y++)
     {
      oldVal[y] = oldVal[y].toUpperCase();
      newVal[y] = newVal[y].toUpperCase();
     }
    
     return Arrays.asList(oldVal).containsAll(Arrays.asList(newVal));
    
    }
     return false;