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

如何高效检测ArrayList中存在指定索引值相同但补充索引值不同的元组?

解决方案:放弃正则,用Java Streams实现高效检测

首先直接给结论:你没法用正则表达式直接实现这个需求,因为正则的核心是字符串模式匹配,而你的需求本质是「按指定维度分组后,检查组内是否存在不同的补充维度值」——这种带有逻辑关联和分组对比的需求,正则根本无法表达,强行写出来也会极度复杂、难以维护,而且性能不会比你原来的方法好。

你的原始方法用双重循环+正则,时间复杂度是O(n²),数据量一大就会卡顿,而用Java Streams结合分组的方式可以把时间复杂度降到O(n),同时逻辑清晰很多。

为什么正则不行?

你需要的是:

  1. 找到所有在指定索引上值相同的行
  2. 检查这些行中是否有至少两行在补充索引上值不同

正则只能做「匹配符合某个模式的字符串」,但它没办法在匹配的同时,把匹配到的字符串和原字符串的补充索引值做对比,更没办法自动分组并检查组内的差异。即使你硬凑出一个正则,也会因为需要包含所有可能的组合而变得无比冗长,完全不具备实用性。

用Java Streams的高效实现

核心思路是:按指定索引的值对行进行分组,然后检查每个分组内的补充索引值是否不唯一。如果存在这样的分组,就说明满足你的条件。

实现代码(简洁版)

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class MatchingChecker {
    public boolean checkMatching() {
        ArrayList<String> rows = new ArrayList<>();
        rows.add("7,2,2,1,1");
        rows.add("7,3,2,1,1");
        rows.add("7,8,1,1,1");
        rows.add("8,2,1,3,1");
        rows.add("8,2,1,4,1");
        rows.add("8,4,5,1,1");
        int[] indices = new int[]{2, 3};
        int supplementaryIndex = 1;

        return rows.stream()
                // 把每行分割成字符串数组,方便取对应索引的值
                .map(row -> row.split(","))
                // 按指定索引的值分组,key是指定索引值的列表;同时收集每组的补充索引值到Set中(自动去重)
                .collect(Collectors.groupingBy(
                        parts -> {
                            // 构建分组key:取出指定索引的所有值组成List
                            List<String> keyParts = new ArrayList<>();
                            for (int idx : indices) {
                                keyParts.add(parts[idx]);
                            }
                            return keyParts;
                        },
                        Collectors.mapping(parts -> parts[supplementaryIndex], Collectors.toSet())
                ))
                // 检查是否有任何一个分组的补充索引值集合大小>1(说明存在不同的值)
                .values()
                .stream()
                .anyMatch(set -> set.size() > 1);
    }
}

代码解释

  1. 分割每行:用map(row -> row.split(","))把每行字符串转成数组,方便快速获取任意索引的值。
  2. 分组逻辑:
    • 分组的key是指定索引对应的所有值组成的List,这样所有在指定索引上值相同的行会被分到同一组。
    • 分组时直接收集每组的补充索引值到Set中,Set会自动去重,所以如果组内有不同的补充索引值,Set的大小就会大于1。
  3. 检查条件:用anyMatch(set -> set.size() > 1)判断是否存在符合条件的分组,一旦找到就立即返回true,无需遍历所有分组。

性能优势

这个方法的时间复杂度是O(n),因为只需要遍历两次数据:一次分组,一次检查分组。相比你原来的O(n²)双重循环,数据量越大,性能提升越明显。而且内存占用也更低,因为分组时只存储了必要的key和补充索引值集合,不需要存储整个行数据。

扩展:处理任意数量的指定索引

上面的代码已经支持任意长度的indices数组,不管你指定1个还是多个索引,分组逻辑都能正常工作,不需要修改核心代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 14:17:29