2011-04-18 48 views
0

在Java中我有两个列表:我在java.util.ArrayList.containsAll中发现了一个错误吗?

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。但是,第一个列表(sats)只包含1个项目,第二个列表包含2.因此,第一个列表(sats)甚至不可能包含第二个列表(sats2)中的所有项目。任何想法为什么或者这是Java JDK中的错误?

我读过另一个StackOverflow问题,这不是执行此类操作的最高性能方法,所以如果任何人有关于如何使其性能更好的建议,那将是非常棒的!

在此先感谢!

+13

你重写了你的Satellite类的'equals'方法吗?如果是显示我们的代码(也可能是'hashCode'方法) – Progman 2011-04-18 20:24:56

+10

[编程的第一条规则;它始终是你的错误](http://www.codinghorror.com/blog/2008/03/the-first-rule-of-programming-its-always-your-fault.html) – 2011-04-18 20:28:50

+0

hashCode在这里并不重要。 ..但等于肯定。 – MeBigFatGuy 2011-04-18 20:54:14

回答

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

我建议您打印两份清单的内容,检查内容对应于你所期望的那样。

+0

在生成的equals方法中的确是一个错误。有点愚蠢的我不检查...谢谢大家! – MCautreels 2011-04-19 05:58:46

1

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

1

来不及回答,但你的问题的第二部分 - 一个更有效的方式做到containsAll是:CollectionUtils.isSubCollection(子集,超集) 这是O(n^2)对O(n)的复杂性

相关问题