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

如何使用Java Stream API获取所有重复元素的索引

Java Stream获取列表重复元素对应索引实现方案

你原有写法的问题在于:input::indexOf只会返回元素第一次出现的索引作为分组键,且分组后收集的是元素值本身而非索引,因此无法得到预期结果。以下是两类需求的具体实现:


需求1:获取「重复元素-对应所有索引」的Map结构

核心思路是先遍历索引,按元素值分组收集所有索引,再过滤掉仅出现1次的非重复元素即可。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

// 示例输入
List<Integer> input = new ArrayList<>(Arrays.asList(312, 312, 195, 195, 195, 851, 335, 851, 99));

Map<Integer, List<Integer>> duplicateValueToIndexes = IntStream.range(0, input.size())
        .boxed()
        // 以列表元素为键,对应索引为值分组
        .collect(Collectors.groupingBy(input::get, Collectors.toList()))
        .entrySet()
        .stream()
        // 仅保留出现次数≥2的重复元素
        .filter(entry -> entry.getValue().size() >= 2)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

运行结果完全匹配预期:{312=[0, 1], 195=[2, 3, 4], 851=[5, 7]}


需求2:获取所有重复元素的索引集合

有两种常见实现方式:

  • 基于上述需求1的结果直接扁平化处理,逻辑直观
List<Integer> allDuplicateIndexes = duplicateValueToIndexes.values()
        .stream()
        .flatMap(List::stream)
        .sorted() // 如需保证索引按升序排列可添加该行
        .collect(Collectors.toList());
  • 不生成中间Map的高效写法:先统计元素出现频次,再遍历索引过滤出重复元素对应的位置,时间复杂度更优
import java.util.function.Function;

// 先统计每个元素的出现次数
Map<Integer, Long> valueCount = input.stream()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

List<Integer> allDuplicateIndexes = IntStream.range(0, input.size())
        .filter(i -> valueCount.get(input.get(i)) >= 2)
        .boxed()
        .collect(Collectors.toList());

两种写法运行结果均为:[0, 1, 2, 3, 4, 5, 7]


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:06:27