使用集合比较字符串数组

时间:2010-03-10 17:29:49

标签: java collections

我有两个字符串数组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));  

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

8 个答案:

答案 0 :(得分:4)

最后,我使用了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

谢谢大家......

答案 1 :(得分:1)

难道你不能只是循环它或使用某种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&gt; 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
}
  • CRAP没有意识到这是因为JAVA认为它是C#。应用 与JAVA相同的逻辑......

答案 2 :(得分:1)

如果数组不包含重复项,在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();
}

如果您认为值得(例如,两个数组通常没有相同数量的元素),您也可以进行简单的大小比较检查。

如果数组中存在重复项,则Set方法将无法正常工作。您需要一个多集,您可以实现自己的,也可以使用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()

答案 3 :(得分:1)

您可以使用TreeMap和不区分大小写的比较器。

答案 4 :(得分:0)

如果你想要自定义比较,

在嵌套循环中检查它。或者如果您拥有大量数据,那么首先对数组进行排序可能会更便宜

答案 5 :(得分:0)

您的样本数据已排序。如果事实证明这是事实,你应该像安德烈所说的那样做,并在数组本身上使用嵌套循环,如果/当你找到一对不等的条目时就会中断。

如果不能保证它们被排序,我会将它们中的每一个转储到HashSet中,然后你可以使用java的Set containsAll方法。

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

1)在插入集合时将字符串加满或缩小。考虑到这一点,我对这种方法并不骄傲,因为你不仅会丢失重复的条目,而且还会根据大小写折叠条目。所以这些列表看起来彼此相同:


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

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

答案 6 :(得分:0)

您可以先检查它们的长度是否相等。然后,您可以将a中的项目放入HashMap并查看b并检查项目是否在那里。

答案 7 :(得分:0)

使用一个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;