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

Java 8 Stream收集为<String,Integer> Map集合的实现求助

解决Java 8 Stream收集到Map的问题

首先得指出你之前写法的核心问题:你在Collectors.toMap里的键映射函数写错了!name -> mapMethodNameConvention是把mapMethodNameConvention这个Function对象本身作为键,而不是映射后的字符串name,这就导致所有键都是同一个Function实例,完全不符合你想要的<String, Integer> Map需求。

下面给你两种符合要求的实现方式,你可以根据自己的习惯选择:

方式一:复用原有分流转逻辑(简单直观)

这种方式和你原来往List里加元素的逻辑最接近,只是把add换成put,同时指定对应的值:

// 先创建目标Map
Map<String, Integer> methodNameMap = new HashMap<>();

// 处理fieldsMappersMetadata,对应值为2
typesMapperGenerationInput.getFieldsMappersMetadata().stream()
    .map(mapMethodNameConvention)
    .forEach(methodName -> methodNameMap.put(methodName, 2));

// 处理fieldsValueProducersMetadata,对应值为1
typesMapperGenerationInput.getFieldsValueProducersMetadata().stream()
    .map(produceMethodNameConvention)
    .forEach(methodName -> methodNameMap.put(methodName, 1));

// 处理constantMappingsMetadata,对应值为1
typesMapperGenerationInput.getConstantMappingsMetadata().stream()
    .map(setConstantValueMethodNameConvention)
    .forEach(methodName -> methodNameMap.put(methodName, 1));

如果遇到重复的方法名,后面的put会覆盖前面的值(比如如果某个方法名同时出现在fieldsMappers和其他来源里,最终值会是1)。如果你想保留优先级更高的2,可以把put换成putIfAbsent,这样只有当键不存在时才会放入:

.forEach(methodName -> methodNameMap.putIfAbsent(methodName, 2));

方式二:合并流后统一收集(更符合Stream风格)

如果你想用更纯粹的Stream链式操作,可以把三个流合并成一个,给每个元素带上对应的数值,再统一收集到Map:

Map<String, Integer> methodNameMap = Stream.concat(
    // 第一个流:映射为<方法名, 2>的Entry
    typesMapperGenerationInput.getFieldsMappersMetadata().stream()
        .map(mapMethodNameConvention)
        .map(name -> new AbstractMap.SimpleEntry<>(name, 2)),
    // 合并另外两个流,都映射为<方法名, 1>的Entry
    Stream.concat(
        typesMapperGenerationInput.getFieldsValueProducersMetadata().stream()
            .map(produceMethodNameConvention)
            .map(name -> new AbstractMap.SimpleEntry<>(name, 1)),
        typesMapperGenerationInput.getConstantMappingsMetadata().stream()
            .map(setConstantValueMethodNameConvention)
            .map(name -> new AbstractMap.SimpleEntry<>(name, 1))
    )
)
.collect(Collectors.toMap(
    Map.Entry::getKey,    // 用Entry的key作为Map的键
    Map.Entry::getValue,  // 用Entry的value作为Map的值
    // 处理重复键:这里选择保留第一个出现的值(比如fieldsMappers的2会被保留)
    (existingValue, newValue) -> existingValue
));

这里的第三个参数是处理重复键的冲突逻辑,如果你想让后面出现的值覆盖前面的,就改成(existing, newVal) -> newVal即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:57:48