gpt4 book ai didi

Java 树形图 : Different object after "put"?

转载 作者:行者123 更新时间:2023-12-01 17:49:51 27 4
gpt4 key购买 nike

我使用从 TreeMap 派生的类和我自己的比较器作为 LinkedHashMap 中的键。使用这个构造,我发现了一些我无法解释自己的奇怪行为。也许你们中的一个人可以提供帮助。我尝试用原语重现我的问题。当我创建基本类型的 TreeMap 时,自然排序顺序应该足够了,并且不需要在 TreeMap 的构造函数中使用比较器,对吗?!

这是 MWE:

package treemapputtest;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

public class TreeMapPutTest {

public static void main(String[] args) {

System.out.println("simple:");
simpleTest();

System.out.println("\n\ncomplex:");
complexTest();
}

private static void simpleTest(){

TreeMap<Integer,String> map = new TreeMap<>();

System.out.println("map: " + map.hashCode() + " | " + Integer.toHexString(map.hashCode()));

map.put(1, "a");

System.out.println("map: " + map.hashCode() + " | " + Integer.toHexString(map.hashCode()));

map.put(2, "b");

System.out.println("map: " + map.hashCode() + " | " + Integer.toHexString(map.hashCode()));

}

private static void complexTest(){

TreeMap<Integer,String> internalMap = new TreeMap<>();
internalMap.put(1, "a");
internalMap.put(2, "b");

System.out.println("prior: " + internalMap.hashCode() + " | " + Integer.toHexString(internalMap.hashCode()));

LinkedHashMap<TreeMap<Integer,String>,Double> myMap = new LinkedHashMap<>();
myMap.put(internalMap, 1.0);

doSomethingWithMyInternalMap(myMap.keySet().iterator().next());

System.out.println("after:");
for (Map.Entry<TreeMap<Integer,String>,Double> entry : myMap.entrySet()){
System.out.println(" " + Integer.toHexString(entry.getKey().hashCode()));
}

}

private static void doSomethingWithMyInternalMap(TreeMap<Integer,String> intern){
intern.put(3, "c");
}
}

输出为:

simple:
map: 0 | 0
map: 96 | 60
map: 192 | c0

complex:
prior: 192 | c0
after:
120

所以我的问题是:为什么当我向 TreeMap 添加内容时 hashCode() 的结果会改变?对于单独的 TreeMap 来说,这并不是什么大问题,但是由于这会创建一个“新对象”/对旧对象的引用发生更改,因此在更新 LinkedHashMap 中的 TreeMap 后我会收到错误。

Object API对于 hashCode() 来说:

The general contract of hashCode is: Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.

在 TreeMap 中添加额外的内容是否会改变 TreeMap 的 equals() 方法中的某些内容?我是否必须以某种方式重写equals()hashCode()

最佳答案

我认为您在这里对hashCode有误解。让我们强调一下您在此处引用的文本中的观点:

The general contract of hashCode is: Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.

每当您在 map 中添加(或删除)数据时,您都会更改其 equals 方法中使用的信息 - 空 map 不等于带有 [1 的 map ->a] 其中,带有 [1->a] 的映射不等于带有 [1->a; 的映射; 2->b]

这与创建新对象无关,并且对旧 map 的引用不会改变。如果您调用System.identityHashCode(map)而不是map.hashCode()您将看到,无论您调用 put 多少次,对象引用都不会更改。

关于Java 树形图 : Different object after "put"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51596234/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com