Java开发Blackjack游戏:多Hand实例共享卡牌列表异常排查
解决Blackjack游戏中Hand2实例共享手牌的问题
问题根源
- 共享集合引用:测试代码中仅创建了一个
ArrayList<Cards>实例,然后将其传入两个Hand2对象的构造函数。Java中对象采用引用传递,因此两个Hand2的hand成员指向同一个List实例,所有发牌操作都会作用于这个共享集合,导致手牌完全一致。 - 手牌总值累加错误:
handValue是类的成员变量,每次调用getHandValue时都会在原有数值基础上累加,而非重新计算,会导致后续获取的数值持续增大。 - 方法权限错误:
addCard方法被定义为private,测试代码无法直接调用,会导致编译失败。
修复后的代码
Hand2类修改版
public class Hand2 { // 每个实例独立维护手牌集合 private List<Cards> hand = new ArrayList<>(); // 无参构造,默认初始化空手牌 public Hand2() { } // 支持传入初始手牌的构造,通过拷贝避免引用共享 public Hand2(List<Cards> initialHand) { this.hand = new ArrayList<>(initialHand); } // 改为public方法,允许外部调用发牌 public Cards addCard(Deck deck) { Cards newCard = deck.dealCard(); hand.add(newCard); return newCard; } // 使用局部变量计算总值,避免累加错误 public int getHandValue() { int handValue = 0; for (Cards card : hand) { handValue += card.getValue(); } return handValue; } @Override public String toString() { return "Hand: " + hand; } }
测试代码修改版
public static void main(String[] args) { Deck deck = new Deck(); deck.shuffle(); // 两个实例各自拥有独立的手牌集合 Hand2 hand = new Hand2(); Hand2 hand2 = new Hand2(); hand.addCard(deck); hand2.addCard(deck); hand2.addCard(deck); System.out.println(hand2); System.out.println(hand.getHandValue()); System.out.println(hand2.getHandValue()); }
修改说明
- 让
hand成员在类内部初始化新的ArrayList,确保每个Hand2实例拥有独立的手牌集合; getHandValue改用局部变量计算总值,每次调用都会重新统计当前手牌的数值;- 修正
addCard的访问权限为public,并优化逻辑直接返回新抽取的卡牌; - 提供带初始手牌的构造方法时,通过
new ArrayList<>(initialHand)拷贝传入的集合,避免引用共享风险。
内容的提问来源于stack exchange,提问作者Jallen
相关产品推荐
相关产品推荐

