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

如何使用Java Stream API分组列表元素并保留元素索引

解决方案

要实现分组时同时保留元素及其索引,核心是先将元素与对应的索引绑定,再进行分组操作。以下是两种可行的实现方式:

方法一:使用AbstractMap.SimpleEntry(Java 8及以上兼容)

利用Java自带的键值对类存储元素和索引,再基于元素分组:

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

public class Main {
    public static void main(String[] args) {
        List<String> l = Arrays.asList("A", "C", "B", "A", "B");

        // 生成元素与索引的配对,再按元素分组
        Map<String, List<AbstractMap.SimpleEntry<String, Integer>>> groupedMap = 
            IntStream.range(0, l.size())
                    .mapToObj(index -> new AbstractMap.SimpleEntry<>(l.get(index), index))
                    .collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey));

        // 按目标格式输出结果
        groupedMap.forEach((key, entries) -> {
            String entryString = entries.stream()
                    .map(entry -> String.format("(%s,%d)", entry.getKey(), entry.getValue()))
                    .collect(Collectors.joining(", ", "[", "]"));
            System.out.printf("%s=%s%n", key, entryString);
        });
    }
}

执行后输出:

A=[(A,0), (A,3)]
B=[(B,2), (B,4)]
C=[(C,1)]

方法二:使用Record(Java 16及以上)

如果使用Java 16+,可以自定义一个Record类来更清晰地封装元素和索引,提升代码可读性:

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

// 定义Record存储元素和索引
record ElementIndexPair(String element, int index) {}

public class Main {
    public static void main(String[] args) {
        List<String> l = Arrays.asList("A", "C", "B", "A", "B");

        Map<String, List<ElementIndexPair>> groupedMap = 
            IntStream.range(0, l.size())
                    .mapToObj(index -> new ElementIndexPair(l.get(index), index))
                    .collect(Collectors.groupingBy(ElementIndexPair::element));

        // 格式化输出
        groupedMap.forEach((key, pairs) -> {
            String pairString = pairs.stream()
                    .map(pair -> String.format("(%s,%d)", pair.element(), pair.index()))
                    .collect(Collectors.joining(", ", "[", "]"));
            System.out.printf("%s=%s%n", key, pairString);
        });
    }
}

核心逻辑说明

  • 用IntStream.range(0, l.size())生成从0到列表长度-1的索引流,避免手动维护索引变量。
  • 通过mapToObj将每个索引与对应的元素绑定,形成包含两者的对象。
  • 最后调用Collectors.groupingBy,以元素作为分组键,收集对应的(元素+索引)对象列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:31:12