调用List.addAll修改从Map取出的列表为何会改动原常量Map的存储值
问题根因
ImmutableMap仅能保证Map结构不可变,即禁止新增、删除、替换key对应的value引用,不会限制value指向的对象本身的内部属性修改。Collectors.groupingBy()默认生成的List实例是可变的ArrayList,你将REVERSE_MAP1.get("FDG")的返回值直接赋值给exampleList,二者指向堆内存中的同一个List实例,调用exampleList.addAll()本质是修改这个共享的List对象,改动自然会同步到REVERSE_MAP1的存储内容中。
修复方案
临时修复:赋值时做List拷贝
获取List时创建新的List实例,避免和原常量Map共享对象:
// 构造新的ArrayList承载原List元素,后续修改只会作用于新实例 List<String> exampleList = new ArrayList<>(REVERSE_MAP1.get("FDG")); exampleList.addAll(REVERSE_MAP2.get("FDG"));
根治方案:常量Map的value设为不可变集合
生成反向Map时直接将value转为不可变List,从根源避免意外修改:
REVERSE_MAP1 = MAP1.entrySet().stream() .collect(Collectors.groupingBy( Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toUnmodifiableList()) ));
采用该方案后如果尝试修改返回的List,会直接抛出UnsupportedOperationException,提前暴露错误操作。
内容的提问来源于stack exchange,提问作者ababuji
相关产品推荐
相关产品推荐

