You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Java扑克游戏检测皇家同花顺时遇ConcurrentModificationException问题求助

解决你的扑克游戏问题:ConcurrentModificationException与皇家同花顺检测优化

先解决你遇到的ConcurrentModificationException异常问题,再给出高效的皇家同花顺检测方案。

一、解决ConcurrentModificationException异常

异常原因分析

你代码中出现这个异常的核心问题,是误用了List.subList()返回的视图列表:

  • cards.subList(10, 15)返回的不是独立新列表,而是原cards列表的视图,它和原列表共享同一个修改计数器(modCount)。
  • 当你调用p1hand.addAll(cards.subList(0, 2))时,本质是修改了原cards列表的结构(视图的修改会同步到原列表),这会让原列表的modCount数值增加。
  • 后续调用p1hand.contains(...)时,方法内部会遍历这个视图列表,遍历过程中会检查当前modCount是否和创建视图时的数值一致,发现不一致就抛出ConcurrentModificationException

解决方案

不要直接使用subList返回的视图,而是创建独立的新ArrayList来存储玩家手牌,让新列表和原列表完全解耦:

// 修改p1hand的创建方式
List<String> p1hand = new ArrayList<>(cards.subList(10, 15));
p1hand.addAll(cards.subList(0, 2));

// 同理修改p2hand的创建方式
List<String> p2hand = new ArrayList<>(cards.subList(10, 15));
p2hand.addAll(cards.subList(2, 4));

这样后续调用contains或其他迭代操作时,就不会再触发修改检查、抛出异常了。

二、高效检测皇家同花顺的方案

你当前的检测逻辑有两个明显问题:一是List.contains(Object o)只能检查列表中是否存在单个元素,无法判断是否包含数组里的所有元素;二是没有考虑玩家是从7张牌中选5张组成牌型的规则。

优化思路

皇家同花顺的核心是同一花色的A、K、Q、J、10,我们可以通过以下步骤高效检测:

  1. 将玩家的7张牌按花色分组,记录每个花色下包含的所有点数。
  2. 检查是否存在某个花色的点数集合,完全包含{"Ace", "King", "Queen", "Jack", "10"}这五个点数。

具体实现代码

// 定义皇家同花顺需要的点数集合(提前初始化,避免重复创建)
private static final Set<String> ROYAL_RANK_SET = new HashSet<>(Arrays.asList("Ace", "King", "Queen", "Jack", "10"));

// 检测手牌是否包含皇家同花顺的方法
private boolean hasRoyalFlush(List<String> hand) {
    // 按花色分组:key是花色,value是该花色下的所有点数集合
    Map<String, Set<String>> suitToRanks = new HashMap<>();
    
    for (String card : hand) {
        // 拆分牌的点数和花色(格式为"X of Y")
        String[] parts = card.split(" of ");
        String rank = parts[0];
        String suit = parts[1];
        
        // 将点数加入对应花色的集合中
        suitToRanks.computeIfAbsent(suit, k -> new HashSet<>()).add(rank);
    }
    
    // 遍历每个花色的点数集合,检查是否覆盖皇家同花顺的所有点数
    for (Set<String> ranks : suitToRanks.values()) {
        if (ranks.containsAll(ROYAL_RANK_SET)) {
            return true;
        }
    }
    
    return false;
}

使用方式

在你的findWinner方法中,直接调用这个方法即可:

// 检测玩家1是否有皇家同花顺
boolean p1royalFlush = hasRoyalFlush(p1hand);
if (p1royalFlush) {
    System.out.println("Player 1 got a royal flush with " + p1hand);
}

// 检测玩家2是否有皇家同花顺
boolean p2royalFlush = hasRoyalFlush(p2hand);
if (p2royalFlush) {
    System.out.println("Player 2 got a royal flush with " + p2hand);
}

方案优势

  • 高效性:只需要遍历7张牌一次完成分组,再对每个花色的点数集合做一次检查,时间复杂度为O(n)(n为手牌数量,这里固定是7)。
  • 准确性:正确处理了7张牌选5张的规则,只要某一花色包含所有皇家同花顺的点数,就判定为符合条件。
  • 可扩展性:如果后续需要检测其他牌型(比如同花顺、四条等),可以基于这个分组逻辑快速扩展。

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

火山引擎 最新活动