这是我无法真正弄清楚的事情:我正在编写纸牌游戏,以检查需要多少手才能完成游戏。问题是我遇到了一个非常奇怪的ConcurrentModificationException
。
这是发生了什么:我已经将卡片组建模为卡片列表。我遍历所有卡片组,并始终删除顶层卡片。
(在“玩家”下面的代码中是一个牌组列表。我已经使用我在'Deck'类中创建的split函数将牌组一分为二来创建了该列表)
public static Deck oneHand(List<Deck> players){
List<Card> hand = new ArrayList<>();
for (int i = 0; i < players.size(); i++) {
hand.add(players.get(i).pop()); //The exception seems to be thrown the second time here
}
//The hand is being played here
}
这是甲板功能。牌组在构造函数中启动。
public class Deck{
private List<Card> cards
public Deck() {
for (int i = 1; i < 13; i++) {
for (int j = 0; j < 4; j++) {
cards.add(new Card(i, Suit.values()[j])); //nice and unique
}
}
Collections.shuffle(cards);
}
public Deck(List<Card> cards) {
this.cards = cards;
}
public List<Deck> split(int n){
if(n > cards.size()){
throw new IllegalArgumentException("Can only split in max " + cards.size() + " elements.");
}
List<Deck> result = new ArrayList<>();
int part = (int) Math.ceil(cards.size()/n);
for (int i = 1; i <= n; i++) {
result.add(new Deck(cards.subList((i-1)*part, Math.min(i*part, cards.size()))));
}
return result;
}
public Card pop(){
return cards.remove(0);
}
}
ConcurrentModificationException
被扔到纸牌上。将其删除,但是为什么呢?我没有遍历卡片,是吗?而且我不删除甲板吗?
如果有帮助:我调试并注意到第二个玩家(但不是第一个玩家)抛出异常,这也是最后一个玩家。提前致谢!
答案 0 :(得分:0)
从您的代码开始,没有Player的实现,给我的印象是您正在共享每个玩家的子列表。
ConcurrentModificationException
,因为您是第一次使另一个子列表的视图无效。假设您有一个列表(A,B,C,D):
startIndex
为0且endIndex
为2的视图。因为索引可能无效,实现记住视图的最后一个“状态”。startIndex
为2且endIndex
为4的视图。因为该索引可能使实现无效记住视图的最后一个“状态”。L1.remove(index)
的意思是view.remove(startIndex + index)
。它的工作原理:视图状态现在已更改。L2.remove(index)
的意思是view.remove(startIndex + index)
。失败:视图状态与子列表不匹配。TL; DR:,您应该在Player实例中复制子列表。