使用对象或整数作为 HashMap 键更好吗?
Posted
技术标签:
【中文标题】使用对象或整数作为 HashMap 键更好吗?【英文标题】:Is it better to use Objects or integers as HashMap keys? 【发布时间】:2013-12-03 03:26:31 【问题描述】:对象的散列如何在 java 的 HashMap 中工作?我在想,与字符串相比,使用整数作为键是否更有效,或者这无关紧要。
如果我有:
String str = "hello";
Object helloObject = new Object();
String 的情况下什么更好?使用整数键:
HashMap<Integer, Object> hashes = new HashMap<Integer, Object>();
hashes.put(str.hashCode(), helloObject);
还是使用字符串键?
HashMap<String, Object> hashes = new HashMap<String, Object>();
hashes.put(str, helloObject);
从插入点和搜索点看什么更有效?
【问题讨论】:
您只需要确保 HashKey Integer 或 String 是唯一的。在Big O Notation
中搜索是 O(1)。它根据密钥直接进入它。这个 O(1) 是使用 HashMap 的要点。
我想知道为什么还没有一个答案提到 Big O Notation
关于搜索 HashMap。
@user2860598 我想知道你为什么用如此错误和令人困惑的例子提到它。 “HashKey 整数或字符串是唯一的”。 “它根据密钥直接进入它”。如果可能的话,我会否决你的 cmets。
【参考方案1】:
你不应该关心这个的效率。您需要关心的是您拥有的用例。在适当的地方使用Integer
s 和String
s。
如果您想了解它的内部工作原理,请查看What issues should be considered when overriding equals and hashCode in Java?。基本上都是关于hashCode()
和equals()
的实现。请注意,密钥也必须是不可变的。
【讨论】:
【参考方案2】:请记住,具有相同哈希码的两个字符串可能不相等。
如果您使用字符串的 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
作为密钥。
【讨论】:
【参考方案3】:首先要做到正确,而不是效率:这段代码
HashMap<Integer, Object> hashes = new HashMap<Integer, Object>();
hashes.put(str.hashCode(), helloObject);
不正确(除了效率低下 *)。
回想一下,哈希码不是唯一的。 as per Java documentation 的唯一要求是相等对象的哈希码相同。但是,具有相同哈希码的对象不一定相等。因此,将哈希映射的键从 String
更改为 Integer
会改变语义:两个完全不同的对象可能会根据它们的哈希码绝对任意地被视为同一个键。
* 如果你对上面的代码 sn-p 效率低下的原因感到好奇,这里有一个自动装箱:
hashCode()
返回一个原始的int
,它被包裹在一个java.lang.Integer
中编译器。在您使用String
时没有创建其他对象的情况下,这通常会导致创建不需要的对象。
【讨论】:
【参考方案4】:这取决于。如果您知道您只会将它用于整数,那么只需使用整数。如果您打算填充各种数据/对象,请使用 Object 并可能使用某种值解析器。
tl;dr:它会只填充整数吗? --> 定义为Integer map,否则使用Object。
【讨论】:
以上是关于使用对象或整数作为 HashMap 键更好吗?的主要内容,如果未能解决你的问题,请参考以下文章