基于List<Object>创建Map:循环转Java 8 Stream实现报错解决
问题场景
将List<Object>转换为HashMap<Key, Object>时执行报错。
使用传统循环可以正常实现需求,但用Java 8 Stream编写忽略重复键的转换逻辑时出现语法错误。
等效的传统循环实现:
Map<String, Field> uniqueFields = new HashMap<>(); for (Field field : allFields) { uniqueFields.put(field.getName(), field); }
存在语法错误的Stream实现代码:
Map<String, Field> uniqueFields1 = allFields.stream() .collect(Collectors.toMap( Field::getName, (oldValue, newValue) -> oldValue));
错误原因
Collectors.toMap()三参数版本的方法定义需要依次传入三个参数:
- key映射规则:从流元素中提取Map的key
- value映射规则:从流元素中提取Map的value
- 重复键合并规则:key重复时如何处理value冲突
编写的代码只传入了key映射规则和合并规则,缺少必填的value映射参数,因此触发语法错误。
正确写法
补全value映射参数即可,要存入的value就是流元素本身,直接传入Function.identity()(等价于field -> field)作为value映射:
Map<String, Field> uniqueFields1 = allFields.stream() .collect(Collectors.toMap( Field::getName, Function.identity(), (oldValue, newValue) -> oldValue ));
上述代码的合并逻辑和传统循环
HashMap.put逻辑完全一致:遇到重复key时保留第一次存入的旧值,丢弃后续重复的新值。
如果需要显式指定返回结果为HashMap类型(默认实现本身就是HashMap,显式声明可避免后续JDK版本变更返回实现类变化的问题),可以使用四参数重载的toMap方法,传入HashMap构造方法引用:
Map<String, Field> uniqueFields1 = allFields.stream() .collect(Collectors.toMap( Field::getName, Function.identity(), (oldValue, newValue) -> oldValue, HashMap::new ));
内容的提问来源于stack exchange,提问作者Shalini Gupta
相关产品推荐
相关产品推荐

