Java 使用集合比较字符串数组

Java 使用集合比较字符串数组,java,collections,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.contai

我有两个字符串数组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));  
List l1=Arrays.asList(a);
列表l2=数组。asList(b);
System.out.println(l2.containsAll(l1));

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

如果需要自定义比较,请在嵌套循环中检查它。或者,如果您有大量的数据集,那么首先对数组进行排序可能会更便宜。您是否可以循环使用它或使用某种linq(抱歉,刚才注意到这是java,您不能使用linq…?)

  • CRAP没有意识到这是为JAVA设计的,他认为这是为C设计的。申请 但JAVA的逻辑相同…

您的样本数据已排序。如果事实上确实如此,那么您应该按照Andrey所说的去做,并在数组本身上使用嵌套循环,如果/当您发现一对不相等的条目时就会中断

如果不能保证对它们进行排序,我会将它们分别转储到一个HashSet中,然后您可以使用java的Set containsAll方法

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

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


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

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

如果数组不包含重复项,在
O(N)
中执行此操作的一种方法是使用表示数组中字符串规范形式的
集。大概是这样的:

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));
}
如果您认为值得,也可以进行简单的大小比较检查(即,如果两个数组的元素数往往不相同)

如果数组中存在重复项,则
Set
方法将无法正常工作。你需要一个multiset,你可以实现你自己的,或者使用googlecollections


还有
O(N log N)
方法可以完成这项工作,包括对字符串进行排序。您可以对两个数组进行排序,然后执行简单的线性检查。必须使用不区分大小写的比较器,事实上它已经作为
字符串存在。不区分大小写\u顺序

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;
}
静态布尔等式canonically3(字符串[]arr1,字符串[]arr2){
int N=arr1.1长度;
如果(arr2.length!=N)返回false;
Arrays.sort(arr1,String.CASE不区分大小写的顺序);
Arrays.sort(arr2,String.CASE不区分大小写的顺序);
对于(int i=0;i

即使阵列包含重复项,最后一种技术也可以工作。它这样做
O(N log N)
。它对作为参数传递的数组进行排序,因此如果原始状态很重要,则您希望传递它们的
克隆()

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

您可以先检查它们的长度是否相等。然后你可以把
a
的项目放在
HashMap
中,然后检查
b
是否有这些项目。

最后,我使用了带有大小写不敏感比较器的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
String[]oldVal={“一”、“二”、“三”、“四”};
字符串[]newVal={“一”、“二”、“三”、“四”};
Set set1=新树集(字符串不区分大小写顺序);
Set set2=新树集(字符串不区分大小写顺序);
set1.addAll(Arrays.asList(oldVal));
set2.addAll(Arrays.asList(newVal));
System.out.println(“--使用树集--”+set1.containsAll(set2));//返回真值
谢谢大家。

使用一个循环-

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;  
String[]oldVal={“一”、“二”、“三”、“四”};
字符串[]newVal={“一”、“二”、“三”、“四”};
if(oldVal.length==newVal.length)
{
//

对于(int y=0;yy)您必须测试l1.containsAll(l2)也很抱歉,我以为你在问关于C的问题,正如我最初看到的列表。我提供了一个答案,但它肯定会帮助你解决你只需要转换为Java的问题。谢谢你的快速回答,我期待着使用Java collection得到答案。@Thomman-很抱歉,我刚刚意识到你在问Java,我以为是C。无论如何,它应该非常相似说谎者,我听说java开发人员看C#很容易转换。所以看看代码,看看是否可以将其转换为适合java的代码。是的,jonH,我使用nested for loop和equalsIgnoreCase实现了。但是我需要一些使用java collection的逻辑。Set containsAll方法区分大小写。@Thomman-很好。我错过了“不区分大小写”是OP问题的一部分。我对此进行了编辑。谢谢。谢谢JRL,正确的方法是使用不区分大小写的比较器的TreeSet。
TreeSet
仅在数组不包含重复项时才起作用。否则,
[“一”,“一”]
将在规范上等同于
[“一”]
。有关详细信息,请参阅我的答案。是的,您是正确的。我的输入是唯一的/没有重复项,很抱歉,无法在问题中添加此项。然后使用
HashSet
并在
O(N)中执行此操作
。HashSet支持不区分大小写的比较器吗?谢谢,我通过使用带有不区分大小写比较器的TreeSet解决了这个问题。当
String[]oldVal={“一”、“一”、“二”};String[]newVal={“一”};
。这不是解决方案!不,当
String[]oldVal={“一”、“二”};String[]newVal={“ONE”};
containsAll
需要双向检查。我忘了解释完整的逻辑,我的要求是比较两个字符串数组,如果两个数组不是e,则返回false
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;
}
 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
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;