如何使用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
相关产品推荐
相关产品推荐

