如何使用Java 8 Stream将带属性枚举转换为HashMap并解决编译报错
编译报错核心原因
- 你编写的代码无法通过编译,本质是类型不兼容问题:
Collectors.toMap()的双参数重载方法,返回值类型是通用的Map接口,并未明确承诺返回具体的HashMap实现类,直接将返回值赋值给HashMap类型的变量,会触发编译期类型检查错误。 - 即便运行时该收集器实际生成的对象是HashMap实例,直接强转赋值也属于违背API约定的写法,JDK后续版本如果调整收集器的默认Map实现,代码会直接抛出运行时错误。
适配当前场景的正确实现方案
提供两种可直接编译运行的写法:
写法1:使用四参数toMap重载,收集过程直接生成HashMap
这种写法没有额外的对象拷贝开销,性能最优,也是Java8 Stream转指定类型Map的标准写法:
HashMap<SheetRows, String> cellsMap = Arrays.stream(SheetRows.values()) .collect(Collectors.toMap( Function.identity(), // key映射为枚举常量本身,等价于原代码的k -> k SheetRows::getValueForTable, // value映射为枚举类持有的字符串值 (oldVal, newVal) -> oldVal, // 合并逻辑:枚举常量不存在重复key,此处仅为满足重载方法的参数要求传入 HashMap::new // 显式指定收集器生成的Map实例为HashMap ));
注意:需要提前导入对应的工具类依赖,包括
java.util.function.Function、java.util.stream.Collectors。
写法2:通过构造器中转生成HashMap
如果觉得四参写法冗余,可以先获取通用Map实例,再通过HashMap的拷贝构造方法生成目标对象,代码可读性更高:
HashMap<SheetRows, String> cellsMap = new HashMap<>( Arrays.stream(SheetRows.values()) .collect(Collectors.toMap( Function.identity(), SheetRows::getValueForTable )) );
两种写法的最终运行结果完全一致,可根据代码风格偏好选择。
内容的提问来源于stack exchange,提问作者hhrzc
相关产品推荐
相关产品推荐

