java 字符串,hashCode
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 字符串,hashCode相关的知识,希望对你有一定的参考价值。
public class Test
public static void main(String[] args)
String a="abc";
String b=new String("abc");
System.out.println(a==b);
System.out.println(a.hashCode()==b.hashCode());
输出:
false
true
为嘛,a和b不是在内存中有两个字符串,他们的物理地址不一样吧?
第二个输出true的原因是什么?
hashCode 返回值是根据字符串内容么?
a==b实际是比较的其引用地址的,因为是指向不同的地址,所以a==b当然是false;
而a.hashcode()==b.hashcode()实际就等同于a.equals(b);实际比较是其内容,跟引用没有关系的!
因为equals和hashcode我们重写的时候都会保持一致的!追问
自己构造实体类的时候一般如何复写hashCode?
比如学生仅有姓名年龄两个属性,如果两个属性相等判断为同一个实例,
这样的话我可以写么:
public int hashCode()
return 1;
不过hashCode和equals方法重新保持一致貌似也很不错的。。。。。
一般如果使用IDE来开发的,都可以自动生成重写的equals和hashcode方法的!
参考技术A a指向字符串常量池,因为“abc”是存在字符串常量池中。b指向堆,因为创建的对象在堆中。
所以,a==b,肯定返回false
hashcode是把你的值(a是“abc”,b也是“abc”),根据一套算法算出来的,算法是固定不变的,传入的值一样,hascode肯定一样。
所以,a的hashcode值与hashcode值,返回true 参考技术B a,b的物理地址是不一样的,
对象是否相等的规则
1 判断两个对象的hashCode是否相等; 如果不相等,认为两个对象也不相等, 完毕.
2 如果相等, 再调用equals方法.
Java中hashcode的计算方式
Java中hashcode的计算方式
String计算hashCode的方式
/**
* hashcode的计算方式为,以31为权重,举例“java”字符串的计算
* j 的 ASCII码 为 106
* a 的 ASCII码 为 97
* v 的 ASCII码 为 118
* 字符串 va 的 hashcode为 118 * 31 + 97
* 字符串 java 的 hashcode为 106 * 31 * 31 * 31 + 97 * 31 * 31 + 118 * 31 + 97
*/
System.out.println(Integer.valueOf('j')); //ASCII码:106
System.out.println(Integer.valueOf('a')); //ASCII码:97
System.out.println(Integer.valueOf('v')); //ASCII码:118
System.out.println(Integer.valueOf('a')); //ASCII码:97
int hashcode = 106 * 31 * 31 * 31 + 97 * 31 * 31 + 118 * 31 + 97;
System.out.println("hashCode计算的值:" + hashcode); //3254818
System.out.println("Objects hashCode:" + Objects.hashCode("java") ); //3254818
System.out.println("String hashCode:" + "java".hashCode()); //3254818
//Objects.hash在上面的计算方式基础上额外增加了31
System.out.println("Objects hash:" + (3254818 + 31)); //3254849
System.out.println("Objects hash:" + Objects.hash("java") ); //3254849
Objects.hash实际上是由Arrays.hashCode(values)运算得出的,计算过程如下:
hashcode有什么用?
当过多对象进行比较时,需要调用n次equals逐个进行比较,会大大降低效率
但是不同的对象可能会生成相同的hashcode值,所以不能根据hashcode值判断两个对象是否相等,但是可以直接根据hashcode值判断两个对象不等
。
如果两个对象的hashcode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过equals方法。
Entity重写hashCode方法
- 为什么要重写equals方法?
如果不重写entity的equals方法,默认调用equals,比较的结果并不准确。
public class Users
private int id;
private String name;
public Users(int id,String name)
this.id = id;
this.name = name;
public static void main(String[] args)
Users user1 = new Users(1,"小妖");
Users user2 = new Users(1,"小妖");
System.out.println(user1.equals(user2)); //打印结果:false
在没有重写equals的情况下,默认调用的是Object的equals,和使用“==”比较的结果一样
- 对于值对象,==比较的是两个对象的值
- 对于引用对象,==比较的是两个对象的地址
public boolean equals(Object obj)
return (this == obj);
而重写equals方法之后,可以根据entity本身的属性来判断,该实体类是否相等
public class Users
private int id;
private String name;
public Users(int id,String name)
this.id = id;
this.name = name;
@Override
public boolean equals(Object o)
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Users users = (Users) o;
return id == users.id &&
Objects.equals(name, users.name);
@Override
public int hashCode()
return Objects.hash(id, name);
public static void main(String[] args)
Users user1 = new Users(1,"小妖");
Users user2 = new Users(1,"小妖");
System.out.println(user1.equals(user2)); //打印结果:true
- 为什么要重写hashCode方法?
重写equal方法时,一定要重写hashCode方法!保证相同的对象返回相同的hash值,不同的对象返回不同的hash值。
如果不重写hashCode方法,调用的是Object中的hashCode方法
public native int hashCode();
重写后的hashcode方法会基于entity的属性计算值
@Override
public int hashCode()
return Objects.hash(id, name);
Entity的hashcode方法主要用于将entity放入HashMap、HashSet等集合框架中。
两个对象相等,hashcode一定相等
两个对象不等,hashcode不一定不等
hashcode相等,两个对象不一定相等
hashcode不等,两个对象一定不等
HashMap中计算hashCode的应用
- hashMap中hashCode的计算
- hashMap的大致存取过程
put操作:
当调用put(key,value)方法的时候,会先对键key调用key.hashcode()方法,根据方法返回的hashcode来找到bucket的位置来存Entry对象。
根据hashcode找到对应的bucket之后,通过equals()方法在对应的链表逐一对比,检查这个链表里有没存在相同的key对象。如果有,则用新的value取代旧的value。如果没有,在链表的尾部加上这个新的Entry对象。
get操作:
当调用get(key)的时候,会调用key的hashcode方法获得hashcode。根据hashcode获取相应的bucket。
由于一个bucket对应的链表中可能存有多个Entry,这个时候会调用key的equals方法来找到对应的Entry
以上是关于java 字符串,hashCode的主要内容,如果未能解决你的问题,请参考以下文章