比较List <string>时是否有一种忽略大小写的简洁方法?

时间:2016-03-31 20:02:37

标签: java string list

现在我有类似的东西:

boolean areListsDifferent = (list1.size() == list2.size()) ? false : true;
for(String string : list1){
    if(!list2.contains(string.toLowerCase())){
        // This sucks because it assumes list2 is all lower case, 
        // which is probably true but presumptuous
        areListsDifferent = true;
    }
}
return areListsDifferent;

这看起来有点冗长,而且我真的不愿意假设第二个列表都是小写的。它使未来的变化更加脆弱。

有更好的方法吗?

3 个答案:

答案 0 :(得分:4)

由于您要比较尺寸,我会假设订单是相关的,因为列表是有序集合。问题中显示的代码忽略了顺序。

要按顺序不区分地比较所有元素,按顺序,您应该并行迭代两个列表。由于get(int)对于所有List实现都不快,因此最好使用Iterator进行并行迭代:

private static boolean equalsIgnoreCase(List<String> list1, List<String> list2) {
    if (list1.size() != list2.size())
        return false;
    for (Iterator<String> iter1 = list1.iterator(), iter2 = list2.iterator(); iter1.hasNext(); )
        if (! iter1.next().equalsIgnoreCase(iter2.next()))
            return false;
    return true;
}

答案 1 :(得分:0)

我假设您要比较 2个列表。

确保两个列表都不为空。

if(list1 == null || list2 == null) return false;

检查尺寸。

if(list1.size() != list2.size()) return false;

检查列表中的元素(包括字符串的排序(?),但不包括大小写)

for(int i = 0 ; i < list1.size() ; i++) {
    // i think equalsIgnoreCase takes care of null strings
    // if it doesn't, do it yourself :)
    String first = list1.get(i);
    String second = list2.get(i);
    if(first == null && second != null)
        return false;
    if(first == null && second == null)
        continue;
    if( !(first.equalsIgnoreCase(second)) )
        return false;
}

如果你到了这里。一切都很好。

return true;

正如Andreas所说,对于像LinkedList这样实现的列表,get(..)会产生糟糕的性能。一个基于iterator的人就像他的回答一样解决了这个问题。

答案 2 :(得分:0)

在您澄清之后:

  

顺序无关紧要。重复也不重要。

然后,我将首先将数据放入具有这些属性的某种SortedSet中,以实现此目的。像这样:

var set1 = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
var set2 = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
set1.addAll(list1);
set2.addAll(list2);
return set1.equals(set2);

与循环遍历一个列表并在另一个列表上重复调用O(N log N)contains)相比,此方法的运行速度(O(N^2))要快-如此一来,一旦您的列表中包含约10个以上的元素,