2011-04-18 24 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)的複雜性

相關問題