对象的散列如何在java的HashMap中工作?我想,与字符串相比,使用整数作为键是否更有效,或者它是否无关紧要。
如果我有:
String str = "hello";
Object helloObject = new Object();
String的情况有什么好处?使用整数键:
HashMap<Integer, Object> hashes = new HashMap<Integer, Object>();
hashes.put(str.hashCode(), helloObject);
或使用String键?
HashMap<String, Object> hashes = new HashMap<String, Object>();
hashes.put(str, helloObject);
从插入点到搜索点有什么效率?
答案 0 :(得分:6)
请记住,具有相同哈希码的两个字符串可能不相等。
如果使用字符串的hashCode而不是字符串本身,则两个不同的字符串可以生成相同的映射键,这可能会导致奇怪的行为。
试试这段代码,看看我的意思。
Map<Integer, String> map = new HashMap<Integer, String>();
map.put("FB".hashCode(), "FB");
map.put("Ea".hashCode(), "Ea");
System.out.println(map.get("FB".hashCode()));
将输出
Ea
,因为
"FB".hashCode() == "Ea".hashCode() // is true
因此,您最好使用String
作为密钥。
答案 1 :(得分:6)
要做的第一件事应该是正确性,而不是效率:这段代码
HashMap<Integer, Object> hashes = new HashMap<Integer, Object>();
hashes.put(str.hashCode(), helloObject);
不正确(除了效率低下 * )。
回想一下,哈希码不是唯一的。唯一要求as per Java documentation是相同对象的哈希码是相同的。但是,具有相同哈希码的对象不一定相等。因此,将哈希映射的密钥从String
更改为Integer
会更改语义:根据哈希代码,两个完全不同的对象可以被绝对任意地视为相同的密钥。
<小时/> * 如果你好奇为什么上面的代码片段效率低下,就会进行自动装箱:
hashCode()
返回一个原始int
,它包含在{{1}中编译器。这通常会导致在使用java.lang.Integer
时没有创建其他对象的情况下创建不需要的对象。
答案 2 :(得分:4)
你不应该关心这个的效率。您需要关心的是您拥有的用例。在适当的位置使用Integer
和String
。
如果您想了解它的内部运作方式,请查看What issues should be considered when overriding equals and hashCode in Java?。它基本上都与hashCode()
和equals()
的实施有关。请注意,密钥也必须是不可变的。
答案 3 :(得分:0)
这取决于。如果您知道只使用Integers,那么只需使用Integer。如果你计划填充所有类型的数据/对象,那么使用Object和它可能是某种值解析器。
tl;博士:它只会被整数填充吗? - &GT;将其定义为整数映射,否则使用Object。