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

使用Stream从两个列表创建值分组映射(无匹配值为空列表)

没问题,我来帮你实现这个映射逻辑!先明确核心规则,再给你代码示例和解释:

实现思路与规则明确

首先得把需求里的规则拆解清楚:

  • 映射的键是sampleBins列表的元素索引(比如示例里sampleBins = [0,10,20,30,40,50,60],对应键0到6)
  • 每个键n对应的数值区间是 [sampleBins[n], sampleBins[n+1))(左闭右开);最后一个键(比如示例里的6)因为没有后续的bin值,所以没有对应区间,直接对应空列表
  • 遍历samples中的每个数值,找到它所属的区间,将其添加到对应键的列表中;所有键必须出现在映射里,没有匹配数值的键对应空列表
Java代码实现(基础版本)

这里用Java实现,和你给出的示例场景匹配,用LinkedHashMap保证键的顺序和索引一致:

import java.util.*;

public class BinValueMapper {
    public static void main(String[] args) {
        // 示例输入
        List<Integer> sampleBins = Arrays.asList(0, 10, 20, 30, 40, 50, 60);
        List<Integer> samples = Arrays.asList(5, 6, 55, 52);
        
        // 初始化映射:每个索引键对应空列表
        Map<Integer, List<Integer>> binToValues = new LinkedHashMap<>();
        for (int i = 0; i < sampleBins.size(); i++) {
            binToValues.put(i, new ArrayList<>());
        }
        
        // 遍历每个样本值,分配到对应区间
        for (int num : samples) {
            int targetKey = -1;
            // 遍历区间找匹配
            for (int i = 0; i < sampleBins.size() - 1; i++) {
                int lowerBound = sampleBins.get(i);
                int upperBound = sampleBins.get(i + 1);
                if (num >= lowerBound && num < upperBound) {
                    targetKey = i;
                    break;
                }
            }
            // 如果找到对应键,添加数值
            if (targetKey != -1) {
                binToValues.get(targetKey).add(num);
            }
        }
        
        // 打印结果验证
        binToValues.forEach((key, values) -> System.out.printf("键%d: %s%n", key, values));
    }
}

运行这段代码后,输出和你期望的完全一致:

键0: [5, 6]
键1: []
键2: []
键3: []
键4: []
键5: [55, 52]
键6: []
优化版本(大数据量场景)

如果sampleBins的长度很大,基础版本的线性查找效率会很低,这里可以用二分查找优化区间匹配逻辑,把时间复杂度从O(n)降到O(logn):

// 替换基础版本中的样本值遍历部分
for (int num : samples) {
    // 用二分查找定位数值位置
    int searchResult = Collections.binarySearch(sampleBins, num);
    int targetKey;
    
    if (searchResult >= 0) {
        // 数值正好等于某个bin值,属于当前索引的区间
        targetKey = searchResult;
    } else {
        // 二分查找返回-(插入点)-1,插入点是第一个大于num的元素索引
        int insertionPoint = -(searchResult + 1);
        targetKey = insertionPoint - 1;
    }
    
    // 验证targetKey是否在有效区间范围内(0到sampleBins.size()-2)
    if (targetKey >= 0 && targetKey < sampleBins.size() - 1) {
        binToValues.get(targetKey).add(num);
    }
}

这个优化版本在处理大量样本数据时会快很多,结果和基础版本完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:00:40