JDK源码阅读-------自学笔记(二)(java.lang.Object重写equals和hashcode源码)

一、前景提要

阅读JDK源码,所有的类的父类都是Object,Objest中定义有public boolean equals(Object obj)方法,它实现了基础的功能比较两个对象时,是看他们是否指向同一个地址的,同一地址返回的就是true,不同地址返回的就是false,但是,有的时候,比较的不仅是是否地址相同,而是其他条件是否相同的时候,就要重写equals和hashCode方法了.

二、场景描述

当你开发登陆功能的时候,你想比较传入的username和password,跟数据库存的username和password是否相同的时候,常见的写法: 从数据库查询到数据,封装到对象中,然后,对象.username.equals传入的对象.username,这样写虽然也能实现功能,但是,不够优雅,所以,面试的时候时常会问你何时重写equals和hashCode,其实,在涉及到对象,对象的比较的时候,都可以使用.

三、实际开发

模拟场景:

  • 1、从数据库获取用户信息,封装到对象中,使用getUserMessage()模拟:

  • 2、模拟登陆验证,使用login方法

  • 3、模拟登陆成功测试.

  • 4、优雅的equals和hashCode重写方式实现

四、源码查阅

Object 的 equals实现

1  /**
2     *  比较当前对象的地址值是否相同 
3     */
4    public boolean equals(Object obj) {
5         return (this == obj);
6     }
View Code

String的equals实现1.7版

 1 public boolean equals(Object anObject) {
 2   
 3         // 传入object和当前对象相等,返回true
 4         if (this == anObject) {
 5             return true;
 6         }
 7         
 8         // 传入object和是否是String类型,返回true
 9         if (anObject instanceof String) {
10             // 对字符串内容进行比较,每个字符比较.相同返回true,否则false
11         
12             String anotherString = (String) anObject;
13             int n = value.length;
14             
15             //  判断长度是否相等
16             if (n == anotherString.value.length) {
17                 char v1[] = value;
18                 char v2[] = anotherString.value;
19                 int i = 0;
20                 
21                 //按照数组的每一位进行比较
22                 while (n-- != 0) {
23                     if (v1[i] != v2[i])
24                         return false;
25                     i++;
26                 }
27                 
28                 return true;
29             }
30         }
31         
32         //不是String类型,返回false
33         return false;
34     }
View Code

String的equals实现1.8版

1  /**
2  * This object (which is already a string!) is itself returned.
3  *  该对象已经是一个字符串,返回其本身
4  * @return  the string itself.
5  */
6  public String toString() {
7         return this;
8  }
View Code

五、实例源码

  1 package com.baidu.www.bean;
  2 
  3 
  4 public class User {
  5 
  6     private Integer id;
  7 
  8     private String userName;
  9 
 10     private String passWord;
 11 
 12     public User() {
 13 
 14     }
 15 
 16     public Integer getId() {
 17         return id;
 18     }
 19 
 20     public void setId(Integer id) {
 21         this.id = id;
 22     }
 23 
 24     public String getUserName() {
 25         return userName;
 26     }
 27 
 28     public void setUserName(String userName) {
 29         this.userName = userName;
 30     }
 31 
 32     public String getPassWord() {
 33         return passWord;
 34     }
 35 
 36     public void setPassWord(String passWord) {
 37         this.passWord = passWord;
 38     }
 39 
 40 
 41     public static User getUserMessage() {
 42         User user1 = new User();
 43         user1.setId(1);
 44         user1.setUserName("zhangsan");
 45         user1.setPassWord("123456");
 46 
 47         return user1;
 48     }
 49 
 50     public static boolean login(User user) {
 51 
 52         return user.getId().equals(getUserMessage().id);
 53     }
 54 
 55     /**
 56      * 自定义对象相等比较,只根据对象的ID是否相等判断,而不是用Object的整个对象比较地址值
 57      *
 58      * @param o 传入对象
 59      * @return 返回对象是否相等
 60      */
 61     @Override
 62     public boolean equals(Object o) {
 63 
 64         // 传入object和当前对象相等,返回true
 65         if (this == o) {
 66             return true;
 67         }
 68 
 69         // 为空或者类型不一样,返回false,即本身是一个Person,传入一个dog类型,类型不一样
 70         if (o == null || getClass() != o.getClass()) {
 71             return false;
 72         }
 73 
 74         // 满足上述后,强制类型转换
 75         User user = (User) o;
 76 
 77         // 如果id不相等,返回false,相等返回true
 78         return id.equals(user.id);
 79     }
 80 
 81     @Override
 82     public int hashCode() {
 83         final int hash = 31;
 84 
 85         int result = 1;
 86 
 87         result = hash * result + id;
 88 
 89         return result;
 90     }
 91 
 92 
 93     /**
 94      * 测试equals和hashCode
 95      *
 96      * @param args 传入值
 97      */
 98     public static void main(String[] args) {
 99 
100 
101         User user = new User();
102         user.setId(1);
103         user.setPassWord("123456");
104         user.setUserName("zhangsan");
105 
106         boolean isLogin = login(user);
107         System.out.println("登陆成果:" + isLogin);
108 
109 
110         boolean equalsLogin = user.equals(getUserMessage());
111         System.out.println("登陆成果:" + equalsLogin);
112 
113 
114     }
115 }
View Code

六、总结

equals的一般实现步骤:

  • 1、传入object和当前对象相等,返回true
  • 2、为空或者类型不一样,返回false,即本身是一个Person,传入一个dog类型,类型不一样
  • 3、满足上述后,强制类型转换
  • 4、如果id不相等,返回false,相等返回true

经验传递

可以使用快捷键生成 IDEA右键---->Generate--->equals and hashCode 会生成自动重写的equals方法和hashcode

posted @ 2020-02-03 14:23  北极的大企鹅  阅读(448)  评论(5编辑  收藏  举报
阅读 - 79万