是否通过改变其参考不良做法来更新 Map 的值?
Is updating the value of a Map by mutating its reference bad practice?
我在我正在处理的代码库中有与此类似的代码:
Map<String, Map<Object, Integer>> mapOfMap = new HashMap<>();
Map<Object, Integer> mapA = mapOfMap.computeIfAbsent(keyParam, k -> new HashMap<>());
mapA.put(objectParam, mapA.getOrDefault(objectParam, 0) + 1);
这样,我们就更新了第一个映射中 'keyParam' 的值,而无需直接调用 put() 方法。
我倾向于更喜欢代码是显式的,并且通常会编写对 'put' 的简单调用。但是,我想知道我是否想得太多了,这种简洁性是我们通过对象引用获得的吗?这可以用 Java 中类似的简洁方式编写,假装对象是不可变的吗?
可以,但不是这种情况。
在这种情况下,代码大概知道它在做什么。对象甚至可能是可变的。解决这个问题的唯一方法是复制值对象,改变它,然后再把它放回去。这在某些程序中可能会非常昂贵,而且我不确定这种风格是否真的更好,我不认为它会更具可读性或总是更不容易出错。这取决于您对不可变对象的总体信任程度。
真正成为问题的地方是发生了不应该发生的突变。但这与地图本身无关。
例如:
在这个 issue on github 中,对本应不可变的列表的引用被传递给确实会改变它的代码的一部分,在这种情况下至少会导致内存泄漏。
我在我正在处理的代码库中有与此类似的代码:
Map<String, Map<Object, Integer>> mapOfMap = new HashMap<>();
Map<Object, Integer> mapA = mapOfMap.computeIfAbsent(keyParam, k -> new HashMap<>());
mapA.put(objectParam, mapA.getOrDefault(objectParam, 0) + 1);
这样,我们就更新了第一个映射中 'keyParam' 的值,而无需直接调用 put() 方法。
我倾向于更喜欢代码是显式的,并且通常会编写对 'put' 的简单调用。但是,我想知道我是否想得太多了,这种简洁性是我们通过对象引用获得的吗?这可以用 Java 中类似的简洁方式编写,假装对象是不可变的吗?
可以,但不是这种情况。
在这种情况下,代码大概知道它在做什么。对象甚至可能是可变的。解决这个问题的唯一方法是复制值对象,改变它,然后再把它放回去。这在某些程序中可能会非常昂贵,而且我不确定这种风格是否真的更好,我不认为它会更具可读性或总是更不容易出错。这取决于您对不可变对象的总体信任程度。
真正成为问题的地方是发生了不应该发生的突变。但这与地图本身无关。
例如:
在这个 issue on github 中,对本应不可变的列表的引用被传递给确实会改变它的代码的一部分,在这种情况下至少会导致内存泄漏。