我有一个代表使用ArrayList
的牌组的程序,我想比较两个牌组,看看它们是否相同(具有相同的大小,相同的牌,并且顺序相同)。我知道你可以为类似int
的类型执行list1.equals(list2),如果两者都是:(1,2,3),它将返回true。当我尝试使用Card
对象列表执行此操作时,它返回false。我创建套牌的代码是:
public DeckofCards(){
for (Suits s : Suits.values()) {
for(Values v : Values.values()){
card = new Card(v,s);
deck.add(card);
}
}
}
我还有一个方法:deckToList
只返回deck
。所以,如果我这样做:
DeckofCards dc = new DeckofCards();
DeckofCards dc2 = new DeckofCards();
List<Card> l1 = dc.deckToList();
List<Card> l2 = dc2.deckToList();
l1.equals(l2);
即使我打印出l1和l2,他们也会以相同的顺序打印相同的牌,因为我没有操纵牌组。现在,如果我将l1
和l2
都设置为dc
,则返回true。由于我使用Object
,equals
方法只是查看地址而不是值?我不确定发生了什么,或者如何正确地比较这两者。
答案 0 :(得分:0)
根据Abstract List's
equals
的实施情况,可以找到ArrayList
的超级equals
您应该覆盖Card
类的@Override
public boolean equals(Object other){
if(this == other) return true;
if(other == null || (this.getClass() != other.getClass())){
return false;
}
Card otherCard = (Card) other;
return (this.value == otherCard.value) &&
(this.color == otherCard.color);
}
方法
在谈论卡片时的良好实施是检查它们的值和颜色是否相等
这样的事情可能会起作用
{{1}}
答案 1 :(得分:0)
你的卡片对象没有实现好等于
如果你在ArrayList(实际上是AbstractList)上看到equals的实现,你会看到在两个列表上迭代并尝试等于元素。
答案 2 :(得分:0)
当您调用构造函数DeckofCards()
时,它会为每个值创建新的List
和新的Card
- 线索是关键字new
。这意味着为所有这些对象分配了新的内存位置。因此,当您创建两个DeckofCards
个对象时,它们每个都包含自己的List
对象,其中包含52个Card
个对象:总共104个单独的Card
个对象。
除非类重写equals
方法,否则它将使用Object
提供的默认值,它只是比较内存位置。现在,List
会覆盖equals
并通过在其包含的每个equals
对象上调用Card
来执行此操作,但由于它不会覆盖equals
,将调用默认的Object
版本。所有Card
都位于不同的内存位置,尽管有些值具有相同的值(在不同的DeckOfCards
个对象中),因此这些List
个对象不相等。
所以建议是覆盖equals
,Ziker的实现看起来很好。但一般情况下,如果您覆盖equals
,请不要忘记覆盖hashcode
,否则您将从HashSet
或HashMap
等集合中获得糟糕的效果。