Java Hashmap实现中的字符串哈希问题
在做了一段时间的研究并查找了一些旧帖子之后,我意识到,当您在Java中使用以字符串为键的Hashmap或Hashtable时,第一轮哈希将应用于每个字符串对象hashCode(显然有第二个哈希函数应用于int hashCode()
的结果),其中默认情况下int hashCode()
与它的调用者在内存中的位置(从我读到的内容)有一些关系。话虽如此,如果我有一个带有开发人员定义的键类的映射,我读到我可以重写int hashCode()
,并使用对象的一些不同字段为每个对象返回尽可能唯一的int。但是,请考虑下面的代码片段,其中包含基元类型的数组。
import java.util.HashMap;
public class test
{
public static void main(String[] args) {
HashMap<char[], int[] > map = new HashMap<char[], int[]>();
String s = "Hello, World";
int x[] = { 1, 2, 3, 4, 5 };
map.put( s.toCharArray(), x );
x = map.get( s );
for ( int i : x )
System.out.print( i );
}
}
程序从NullPointerException
崩溃当然是因为map.get( s );
返回null。我怀疑发生这种情况是因为map.put()
和map.get()
之间有两个不同的引用。我希望程序输出的是123445
我的问题是:如何让上面的代码片段通过键的值与键的引用来查找键?也就是说,如何让程序输出12345
编辑: 我使用hashmap作为查找表。我正在从文件中读取字符串,需要一种快速方法来确定我刚才读取的字符串是否在表中
# 1 楼答案
来自Oracle文档
显然s.equals(s.toCharArray())是错误的。他们甚至不是同一个阶级
但是,您可以使用一个类作为键,该类重写equals(),在您的情况下返回true。 例如:
# 2 楼答案
只需使用字符串作为映射的键
字符串是不可变的,因此它是作为映射键的好选择
添加另一个阵列:
输出值:
给予
给予
# 3 楼答案
equals
函数相等,则它将检索项。为什么您认为char[]
有一个被重写的equals
,允许它正确地将自身与字符串进行比较?甚至在彼此之间?它不会覆盖equals,并且仅当它是同一实例时才会返回true李>根据您的评论,我理解您希望能够编辑字符串。在你把它放到地图上之前没关系。但是当对象是映射中的键时,不要以可能更改哈希代码或相等值的方式更改对象。最好的方法是使用自定义对象。阵列不适用于此
如果您真的想在映射中动态更改值,请使用
BiMap
(或者自己执行forcePut
中的操作)# 4 楼答案
有很多方法可以做到这一点。您可以做的最小更改之一是在调用
put()
之前只保存char[]
,并将相同的更改用作get()
的参数:这里重要的一点是,您需要使用与
put()
相同的对象来get()