程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-06(2)

面试题hashCode和equals

发布于2021-04-18 14:23     阅读(906)     评论(0)     点赞(30)     收藏(3)


参考文献:

 看似简单的hashCode和equals面试题,竟然有这么多坑!

  1. import java.util.*;
  2. class Student{
  3. String name;
  4. int age;
  5. public Student(String name, int age) {
  6. this.name = name;
  7. this.age = age;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public int getAge() {
  13. return age;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public void setAge(int age) {
  19. this.age = age;
  20. }
  21. @Override
  22. public boolean equals(Object o) {
  23. if (this == o) return true;
  24. if (o == null || getClass() != o.getClass()) return false;
  25. Student student = (Student) o;
  26. return age == student.age && Objects.equals(name, student.name);
  27. }
  28. @Override
  29. public int hashCode() {
  30. return Objects.hash(name, age);
  31. }
  32. }
  33. public class Main {
  34. public static void main(String[] args) {
  35. Student s1=new Student("mingming",12);
  36. Student s2=new Student("mingming",12);
  37. /*
  38. 和equals()一样,Object里hashCode()里面只是返回当前对象的地址,
  39. 如果是这样的话,那么我们相同的一个类,new两个对象,
  40. 由于他们在内存里的地址不同,则他们的hashCode()不同且equals=false
  41. 因此可以同时放到hashset
  42. */
  43. System.out.println(s1.hashCode()+" "+s2.hashCode());
  44. System.out.println(s1.equals(s2));//false
  45. HashSet<Student> set = new HashSet<>();
  46. set.add(s1);
  47. set.add(s2);
  48. System.out.println(set.size());//2
  49. }
  50. }

结果输出:

1.不equals和hascode的结果:

2083562754  1239731077
false
2

2.只重写equals的结果 

2083562754  1239731077
true
2

3.重写equals和hascode之后的结果:

761311971  761311971
true
1

结论:

所以如果我们的对象要想放进hashSet,并且发挥hashSet的特性(即不包含一样的对象),则我们就要重写我们类的hashCode()和equals()方法了。像String,Integer等这种类内部都已经重写了这两个方法。

当然如果我们只是平时想对比两个对象 是否一致,则只重写一个equals(),然后利用equals()去对比也行的。

hascode相等,equals一定相等

重写equals+hascode  equals为true ,hascode相等

重写equals                  equals为true ,hascode不一定相等

应用:

hash容器中,比如HashSet,HashMap,HashTable等等,要求对象不能重复,添加新的对象要进行对比

 

 问题1、equals()既然已经能实现对比的功能了,为什么还要hashCode()呢?

因为重写的equals()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。

 问题2、hashCode()既然效率这么高为什么还要equals()呢?

因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出(PS:以下两条结论是重点,很多人面试的时候都说不出来): 

问题3:为什么要重写hascode()

避免出现,两个对象明明是相等(equals()=true),而hashCode却不一样。 如上的结果2.

2083562754  1239731077
true
2

造成的结果就是:

当你用其中的一个作为键保存到hashMap、hasoTable或hashSet中,再以“相等的”找另一个作为键值去查找他们的时候,则根本找不到。

 问题4:什么时候需要重写hascode()

一般的地方不需要重载hashCode,只有当类需要放在HashTable、HashMap、HashSet等等hash结构的集合时才会重载hashCode。

阿里巴巴开发规范也明确规定:

 



所属网站分类: 技术文章 > 博客

作者:飞翔公园

链接:http://www.javaheidong.com/blog/article/159853/602c13e411ab3d9425c1/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

30 0
收藏该文
已收藏

评论内容:(最多支持255个字符)