重写HashMap get方法的第二种实现未生效原因咨询
原因说明
第二种写法没有生效的核心原因是变量引用被重新赋值,你自定义重写了get方法的HashMap实例被直接丢弃:
- 代码中
Map<String, List<T>> map = new HashMap<>() { /* 重写get方法 */ }这一行,确实创建了一个继承HashMap、实现了自定义get逻辑的匿名类实例。 - 但紧接着执行的
map = list.stream().collect(...)会直接将map变量的引用指向groupingBy收集器返回的全新普通HashMap实例——这个实例是JDK收集器内部创建的标准HashMap,没有重写get方法,和你之前自定义的匿名类实例没有任何关系。之前创建的自定义Map实例因为没有任何引用持有,会被垃圾回收。 - 第一种写法能正常工作,是因为你始终没有修改自定义
tempMap的引用,只是通过putAll将流收集得到的所有数据存入自定义实例中,最终返回的一直是持有重写后get方法的对象,所以逻辑符合预期。
优化实现方案
不需要手动创建Map再调用putAll拷贝数据,直接使用groupingBy的三参数重载,指定自定义Map作为结果容器,可以一步实现需求:
public Map<String, List<T>> getMailBox() { return list.stream() .collect(java.util.stream.Collectors.groupingBy( Sendable::getTo, // 传入自定义Map的供应器,作为最终的结果容器 () -> new HashMap<>() { @Override public List<T> get(Object key) { Optional<List<T>> optional = Optional.ofNullable(super.get(key)); return optional.orElse(Collections.emptyList()); } }, java.util.stream.Collectors.mapping( Sendable::getContent, java.util.stream.Collectors.toList() ) )); }
注意:
Collections.emptyList()是不可变列表,如果调用方获取到不存在key对应的空列表后,尝试调用add/remove等修改方法会抛出异常。如果需要返回可变空列表,将返回值替换为new ArrayList<>()即可。
内容的提问来源于stack exchange,提问作者Valery Proskuryakov
相关产品推荐
相关产品推荐

