我有两个ArrayLists,一手牌,然后是“运行”牌(牌是对象。)我试图通过卡片的“运行”启动,并从手中删除那些特定的牌。
我在不同的方法中使用完全相同的代码,它的工作非常棒。由于某种原因,下面的代码不是从Hand中删除任何“运行”卡,我无法弄清楚原因。调试器显示传递正确卡的方法;任何想法?
private ArrayList<ArrayList<Card>> meldDesktop;
public void addMeldRun(ArrayList runToAdd, Hand playerHand, Player player){
this.meldDesktop.add(runToAdd);
//after adding the run to the meld desktop, remove them from the player's
//hand and get points
Iterator<Card> testRoll = runToAdd.iterator();
while (testRoll.hasNext()){
int points = 0;
Card removeCard = testRoll.next();
playerHand.removeCard(removeCard);
points = removeCard.pointValue() + points;
player.setScore(points);
}
}
public ArrayList removeCard (Card newCard){
handCard.remove(newCard);
//Collections.sort(handCard);
return handCard;
}
答案 0 :(得分:2)
可能问题是卡片对象被复制/克隆一些如何因此它们与playerHand对象中的对象不同。因此他们没有通过手中的等号检查卡。删除(newCard);
你可以用以下方法测试:
boolean removed = handCard.remove(newCard);
System.out.println(newCard.pointValue() + " removed = " + removed);
很可能这个问题在于如何将卡添加到runToAdd对象中。
你也可以在循环时改善你,甚至更好地使用增强的for循环:
int points = 0;
for (Card removeCard : testRoll){
playerHand.removeCard(removeCard);
points += removeCard.pointValue();
}
player.setScore(points);
让我知道测试的结果,我会用你应该看到的内容更新答案。
答案 1 :(得分:2)
您没有提供足够的信息来为您的特定问题做出正确的诊断/解释。
然而,List.remove(elem)
无效的解释只有一个合理的解释。那就是elem
不在列表中“...”根据javadocs中“in”的定义语义。
打破这一点:
可能只是元素不在列表中...无论如何。
也可能是元素不在列表中,因为equals(Object)
方法的实现对于您期望的“在列表中”语义是不正确的。
remove
API中List
的规范是它使用equals(Object)
方法。如果elem.equals(obj)
对于列表中的某些true
为obj
,则该对象将被删除。
但这就是问题。从equals(Object)
继承的java.lang.Object
的默认实现是简单地比较对象引用。如果您没有覆盖equals(Object)
课程的Card
,并且您的应用程序会创建多个(例如)“俱乐部之王”的实例......那么remove
可能会失败,因为您试图删除错误的。
解决此问题的另一种方法是使用调试器单步执行remove
方法(观察局部变量等)以查看实际发生的情况。特别是,查找 要与要删除的元素(Card
)匹配的点。
但是,我希望这只能证实我上面所说的内容。
需要注意的是,代码需要执行以下操作之一:
确保“俱乐部之王”只创造一次;即永远不要复制它,永远不要复制它,永远不要new
另一个实例等,或者
覆盖equals(Object)
以按值比较Card
个对象;即所以“俱乐部之王”的所有情况都被视为平等。显然,语义将取决于你正在模拟的游戏规则......但你需要自己考虑一下。