You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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());
}

修改说明

  1. 让hand成员在类内部初始化新的ArrayList,确保每个Hand2实例拥有独立的手牌集合;
  2. getHandValue改用局部变量计算总值,每次调用都会重新统计当前手牌的数值;
  3. 修正addCard的访问权限为public,并优化逻辑直接返回新抽取的卡牌;
  4. 提供带初始手牌的构造方法时,通过new ArrayList<>(initialHand)拷贝传入的集合,避免引用共享风险。

内容的提问来源于stack exchange,提问作者Jallen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:16:05