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 }
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 }
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 }
五、实例源码
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 }
六、总结
equals的一般实现步骤:
- 1、传入object和当前对象相等,返回true
- 2、为空或者类型不一样,返回false,即本身是一个Person,传入一个dog类型,类型不一样
- 3、满足上述后,强制类型转换
- 4、如果id不相等,返回false,相等返回true
经验传递
可以使用快捷键生成 IDEA右键---->Generate--->equals and hashCode 会生成自动重写的equals方法和hashcode
十年磨一剑,一剑破万法