我在java.util.ArrayList.containsAll中发现了一个错误吗?

时间:2011-04-18 20:22:42

标签: java list collections arraylist

在Java中我有两个列表:

List<Satellite> sats = new ArrayList<Satellite>();
List<Satellite> sats2 = new ArrayList<Satellite>();

Satellite sat1 = new Satellite();
Satellite sat2 = new Satellite();

sats.add(sat1);

sats2.add(sat1);
sats2.add(sat2);

当我在第一个列表中执行以下containsAll方法时:

sats.containsAll(sats2); //Returns TRUE!

它返回true。但是第一个List(sats)只包含1个项目,第二个列表包含2.因此,第一个列表(sats)甚至不可能包含第二个列表(sats2)中的所有项目。知道为什么或这是Java JDK中的错误?

我在另一个StackOverflow问题中读到,这不是执行此类操作的最佳方式,因此,如果有人建议如何使其更高效,那就太棒了!

提前致谢!

3 个答案:

答案 0 :(得分:5)

正如@Progman所指出的那样,你可能会覆盖equals中的Satellite方法。

以下程序打印false

import java.util.*;

class Satellite {
}

class Test {
    public static void main(String[] args) {
        List<Satellite> sats = new ArrayList<Satellite>();
        List<Satellite> sats2 = new ArrayList<Satellite>();

        Satellite sat1 = new Satellite();
        Satellite sat2 = new Satellite();

        sats.add(sat1);

        sats2.add(sat1);
        sats2.add(sat2);

        System.out.println(sats.containsAll(sats2));
    }
}

ideone.com demo

我建议您打印两个列表的内容,并检查内容是否符合您的预期。

答案 1 :(得分:1)

对于许多类,有意义的是,以相同方式创建的两个对象(例如new Satellite())将被视为相等。请注意,containsAll并不关心Collection包含的对象的副本数量,只是它包含至少一个 distinct 元素。 Collection它已经给出了。例如,如果您的List a包含[A, A],而列表b只包含[A],那么b.containsAll(a)a.containsAll(b)都会返回true。这可能类似于这里发生的事情。

答案 2 :(得分:1)

回复太迟了,但你的问题的第二部分 - 一个更有效的方法做containsAll是:CollectionUtils.isSubCollection(subSet,superSet) 那就是O(n ^ 2)vs O(n)复杂度