为什么stringObject
的哈希码是我提供的字符串?
String s = new String(); // here the hascode is 0.
但是当我得到我创建的某个对象的哈希码时。
testClass o = new testClass(); // the hashcode is some random number.
我的问题是两者有什么区别?我的理解是hashCode()
来自Object
班,这是所有班级的母亲。
答案 0 :(得分:7)
为什么stringObject的哈希码是我提供的字符串? 恩。 String s = new String(“hello”); //这里的hascode是你好的。
那不是真的
hashCode()
是一个int数
您似乎将hashcode()与toString()
混淆如果您想查看hashcode()
String str = "hello";
System.out.println(str.hashcode());//will print some int number
System.out.println(str);//will invoke toString() which will return `hello`
答案 1 :(得分:0)
我认为您将hashCode()
与toString()
混为一谈。
每个对象的默认toString()
实现确实是<classname>@<some number>
,并且该数字恰好是十六进制中对象的哈希码,但是可以(并且应该)被可以提供的类覆盖更有意义的字符串表示。对于字符串,明显的字符串表示本身就是。
答案 2 :(得分:0)
String s = new String(“hello”); 这个哈希码永远不会是 Hello ,因为 hashCode()方法会返回type是 int 而不是字符串
答案 3 :(得分:0)
String
是Java库中提供的类。因此,hashCode()
方法已被此类的创建者覆盖以反映它。请注意,哈希码是一个int值。
当您创建一个类时,您希望覆盖hashCode()
和equals()
方法,以便能够比较您的对象,并做其他很酷的事情(将它们放在{{1例如)。
您需要注意如何实现HashMap
,因为您希望尊重一般合同,即根据hashCode()
方法,如果两个对象相等,则它们具有相同的{{1} 1}},而相反的情况不一定是真的(但建议)。
您可以在此处找到更深入的解释 - http://www.javaworld.com/community/node/1006
答案 4 :(得分:0)
这里有一些问题:
hashCode()
会返回一个整数,您可能会对toString()
Object
同时包含hashCode()
和toString()
方法。但是,Object
的任何子类都可以override这种方法。当调用该方法时 - 将调用动态类型的方法,因此对于String
,将调用String.hashCode()
而不是Object.hashCode()
[{1}}的相同想法]。这称为dynamic dispatch。例如:
toString()
在上面的代码快照中,系统会调用public static class A {
public void foo() {
System.out.println("A");
}
}
public static class B extends A{
@Override
public void foo() {
System.out.println("B");
}
}
public static void main(String[] args) throws Exception {
A a = new B();
a.foo();
}
,并会打印B.foo()
,因为B
会覆盖B
,动态类型为foo()
}是a
,因此调用了B
。
在您的情况下:由于B.foo()
会覆盖String
,然后会调用hashCode()
,而对于String.hashCode()
- 它不会覆盖testClass
,因此原始hashCode()
被调用。
答案 5 :(得分:0)
方法hashCode()
始终返回一个整数,该整数是对象的hash value。类Object
中提供了一个nativ实现。如果要创建自己的类型哈希,则必须覆盖hashCode()
。
toString()
将返回对象的字符串表示形式,并返回hashCode()
(如上所述)对象的哈希值。
班级String
会覆盖hashCode()
。这就是String
:
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
答案 6 :(得分:0)
我认为您因为空字符串的哈希码为 0 而感到困惑。 Hashcode 始终是一个整数,由该类可用的 hashcode 函数计算。 现在,任何自定义类的哈希码由对象类(默认父级)哈希码方法提供,该方法以 int 形式返回该对象的内存地址。(如果没有被自定义类覆盖)
现在您可以将 String 视为一个自定义类,但由其他一些用户创建,这些用户覆盖了 String 类中字符串的哈希码函数,该函数现在计算如下: S[0]*31^(n-1)+S[1]*31^(n-2)+...+s[n] ,0 表示空字符串。 用于评估上述表达式的所有计算都是java的整数计算。你可以参考https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode()
java 的 String 类重写了 hascode 函数,这样当你在两个不同的 String 对象上调用 hashcode 时,它们的字符串相同,会得到相同的 hashcode;在散列数据结构(如散列图)中使用散列技术时,这通常很重要。 所以这个被覆盖的函数为两者提供了相同的哈希码 String s1=new String("你好") 和 String s2=new String("你好") ;而在内存中,它们被存储为不同的字符串。 现在,如果您希望您的自定义类基于该类的某些属性具有相同的哈希码,您可以像 String 一样根据存储在其中的实际字符串覆盖类中的哈希码。
所以在你的情况 1;你得到 0,在 cade 2 中你得到一些 int 形式的内存位置,如上所述。