在标准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

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


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


当前回答

下面是一种比较两个集合的方法,它考虑了其中的重复。因此,集合大小不一定相同。因此,它会在'actual'中寻找'expected':

    private static <T> boolean containsAllExpected(Collection<T> actual, Collection<T> expected) {
        if (actual == null && expected == null) {
            return true;
        }
        if (actual == null || expected == null) {
            return false;
        }
        Collection<T> a = new ArrayList<>(actual);
        Collection<T> e = new ArrayList<>(expected);

        Iterator<T> ei = e.iterator();
        while (ei.hasNext()) {
            T item = ei.next();
            if (a.contains(item)) {
                ei.remove();
                a.remove(item);
            } else {
                return false;
            }
        }

        return true;
    }

享受:)

其他回答

汤姆的回答很好,我完全同意他的回答!

这个问题的一个有趣方面是,您是否需要List类型本身及其固有顺序。

如果不是,你可以降级为Iterable或Collection,这让你在传递数据结构时具有一定的灵活性,这些数据结构是根据插入时间排序的,而不是在你想检查的时候排序。

如果顺序无关紧要(并且没有重复的元素),可以考虑使用Set。

如果顺序很重要,但由插入时间定义(并且没有重复),则考虑LinkedHashSet,它类似于TreeSet,但按插入时间排序(重复项不计算)。这也给了你O(1)个平摊访问,而不是O(log n)。

private boolean listHaveEqualObjects(List<?> list1, List<?> list2){
    return list1.containsAll(list2) && list2.containsAll(list1);

下面是一种比较两个集合的方法,它考虑了其中的重复。因此,集合大小不一定相同。因此,它会在'actual'中寻找'expected':

    private static <T> boolean containsAllExpected(Collection<T> actual, Collection<T> expected) {
        if (actual == null && expected == null) {
            return true;
        }
        if (actual == null || expected == null) {
            return false;
        }
        Collection<T> a = new ArrayList<>(actual);
        Collection<T> e = new ArrayList<>(expected);

        Iterator<T> ei = e.iterator();
        while (ei.hasNext()) {
            T item = ei.next();
            if (a.contains(item)) {
                ei.remove();
                a.remove(item);
            } else {
                return false;
            }
        }

        return true;
    }

享受:)

除了劳伦斯的答案,如果你也想让它为零安全:

private static <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
    if (list1 == null)
        return list2==null;
    if (list2 == null)
        return list1 == null;
    return new HashSet<>(list1).equals(new HashSet<>(list2));
}

你可以使用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)