在标准Java库中,找出两个list是否包含完全相同的元素的最简单方法是什么?

这两个list是否为相同实例并不重要,这两个list的类型参数是否不同也不重要。

e.g.

List list1
List<String> list2; 
// ... construct etc

list1.add("A");
list2.add("A"); 
// the function, given these two lists, should return true

我知道可能有什么东西在盯着我的脸:-)


编辑:为了澄清,我正在寻找完全相同的元素和元素的数量,按顺序。


当前回答

!集合。disjoint(Collection1, Collection2)如果它们有相同的元素,则返回true

其他回答

很晚才加入这个派对,但想添加这个空安全检查:

Objects.equals(list1, list2)

示例代码:

public static '<'T'>' boolean isListDifferent(List'<'T'>' previousList,
        List'<'T'>' newList) {

    int sizePrevoisList = -1;
    int sizeNewList = -1;

    if (previousList != null && !previousList.isEmpty()) {
        sizePrevoisList = previousList.size();
    }
    if (newList != null && !newList.isEmpty()) {
        sizeNewList = newList.size();
    }

    if ((sizePrevoisList == -1) && (sizeNewList == -1)) {
        return false;
    }

    if (sizeNewList != sizePrevoisList) {
        return true;
    }

    List n_prevois = new ArrayList(previousList);
    List n_new = new ArrayList(newList);

    try {
        Collections.sort(n_prevois);
        Collections.sort(n_new);
    } catch (ClassCastException exp) {
        return true;
    }

    for (int i = 0; i < sizeNewList; i++) {
        Object obj_prevois = n_prevois.get(i);
        Object obj_new = n_new.get(i);
        if (obj_new.equals(obj_prevois)) {
            // Object are same
        } else {
            return true;
        }
    }

    return false;
}

这应该在O(n)时间内完成。

public static <T> boolean isEqualCollection(Collection<T> c1, Collection<T> c2){
    if(nonNull(c1) && nonNull(c2)){
        Map<T, Long> c1Counts = c1.stream().collect(Collectors.groupingBy(i -> i, Collectors.counting()));
        for(T item : c2) {
            Long count  = c1Counts.getOrDefault(item, 0L);
            if(count.equals(0L)){
                return false;
            } else {
                c1Counts.put(item, count - 1L);
            }
        }
        return true;
    }
    return isNull(c1) && isNull(c2);
}

你可以使用Apache的org.apache.commons.collections库: http://commons.apache.org/collections/apidocs/org/apache/commons/collections/ListUtils.html

public static boolean isEqualList(java.util.Collection list1,
                              java.util.Collection list2)

我在评论里发了一堆东西,我认为它有自己的答案。

正如这里所有人所说,使用equals()取决于顺序。如果你不关心顺序,你有三种选择。

选项1

使用containsAll()。在我看来,这个选项并不理想,因为它提供了最坏情况下的性能O(n²)。

选项2

这种说法有两种变体:

2a)如果你不关心保持列表的顺序……在两个列表上使用Collections.sort()。然后使用equals()。这是O(nlogn)因为你做了两次排序,然后是O(n)比较。

2b)如果你需要保持列表的顺序,你可以先复制两个列表。然后,您可以在两个复制的列表上使用解决方案2a。然而,如果复制非常昂贵,这可能没有吸引力。

这导致:

选项3

如果你的要求和2b部分一样,但是复制太贵了。您可以使用TreeSet为您进行排序。将每个列表转储到它自己的TreeSet中。它将在集合中排序,原始列表将保持不变。然后对两个树集执行equals()比较。TreeSetss可以在O(nlogn)时间内构建,equals()是O(n)。

你选吧:-)。

编辑:我差点忘了Laurence Gonsalves指出的同样的警告。TreeSet实现将消除重复项。如果关心重复项,则需要某种排序的多集。