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

如何用Java Stream实现基于索引分组的嵌套值计数Map?

问题描述

给定List<Integer> l和整数因子f,需要用Stream创建Map<Integer, Map<Integer, Long>> m:外层Map的键是列表索引除以f的结果,内层Map是对应分组中各值的出现次数。

示例

当列表为{1,1,1,4}、f=2时,结果为:

0 -> 
  {
   1 -> 2
  }
1 -> 
  {
   1 -> 1
   4 -> 1
  }

已有循环实现

Map<Integer, Map<Integer, Long>> m = new HashMap<>();
for (int i = 0; i < l.size(); i++) {
 m.computeIfAbsent(i/f, k -> new HashMap<>())
  .compute(l.get(i), (k, v) -> v==null?1:v+1);
}

已知基础写法

已经掌握用Stream做简单分组计数的写法:

Map<Integer, Long> m = l.stream()
 .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

现在的困惑是不知道如何结合索引分组完成嵌套统计,考虑用IntStream.range获取索引,但不清楚正确的计数收集方式。


解决方案

可以通过IntStream.range遍历索引,将索引与元素配对后,用嵌套的groupingBy完成双层分组统计,代码如下:

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

public class StreamGroupingDemo {
    public static void main(String[] args) {
        List<Integer> l = List.of(1, 1, 1, 4);
        int f = 2;

        Map<Integer, Map<Integer, Long>> result = IntStream.range(0, l.size())
                // 将索引和对应元素打包成数组,保留两者关联关系
                .mapToObj(i -> new int[]{i, l.get(i)})
                // 外层分组:按索引除以f的结果作为键
                .collect(Collectors.groupingBy(
                        arr -> arr[0] / f,
                        // 内层分组:对每个子组的元素统计出现次数
                        Collectors.groupingBy(
                                arr -> arr[1],
                                Collectors.counting()
                        )
                ));

        // 打印验证结果
        result.forEach((outerKey, innerMap) -> {
            System.out.println(outerKey + " -> ");
            innerMap.forEach((value, count) -> System.out.println("  " + value + " -> " + count));
        });
    }
}

代码逻辑说明

  1. 生成索引流:IntStream.range(0, l.size())生成覆盖所有列表元素索引的流,确保每个元素的位置信息都能被获取。
  2. 关联索引与元素:用mapToObj把索引和对应元素包装成数组,这样在流处理中能同时操作索引和元素值。
  3. 外层分组:以arr[0]/f作为分组键,对应外层Map的键,实现按索引分段的需求。
  4. 内层计数:每个外层分组内,再以元素值为键,用Collectors.counting()统计该值在当前分段中的出现次数,生成内层的计数Map。

这个实现和循环版本的逻辑完全一致,用Stream API完成了嵌套分组统计的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:00:16