java.lang.Object类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类都可以使用。在对象实例化的时候,最终找的父类就是Object。
1. toString方法
public String toString():返回该对象的字符串表示。
toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值。
由于toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。
public class Person {private String name;private int age;@Overridepublic String toString() {return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';}// 省略构造器与Getter Setter}
2. equals方法
public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。
Object类中默认进行==运算符的对象地址比较,只要不是同一个对象,结果必然为false。
重写equals(Object obj)的模板:
@Overridepublic boolean equals(Object obj) {//1. 是否是同一个对象if(this == obj){return true;}//2. 是否为空//3. 是否是要比较的类的对象(防止强制转型失败)if((obj==null) || (obj instanceOf Student){return false;}//4. 返回判断结果return this.name.equals((Student)anObject.name); //不要忘了做向下转型!}
当比较基本类型变量时,使用==; 当比较引用类型变量时,使用equals().
3. hashCode方法
public int hashCode(): 返回对象的哈希值,普通的十进制整数。默认情况下如果没有重写hashCode()方法,每个对象运行hashCode()的结果都不同。如果一个类重写了equals()方法,则必须重写hashCode()方法。2个对象的equals()方法返回true的话,其hashCode()必须返回相同的值。否则对于HashSet, HashMap, HashTable等基于hash值的类就会出现问题。
hash值是如何被计算出来的呢?

看一下String的hashCode: String是以每个字母的值来计算hash的,因此当字母相同时,String也是equals。
public int hashCode() {int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;}
Objects.hash(Object…o)
我们再看一下一般应该如何定义一个hashCode()方法:Objects.hash(o…objs)
public class Employee {private String name;private String phone;private String address;@Overridepublic boolean equals(Object obj) {if (obj instanceof String) {Employee other = (Employee) obj;return (this.name.equals(other.name) && this.phone.equals(phone));}return false;}@Overridepublic int hashCode() {return 7*name.hashCode() + 11*phone.hashCode();}public int hashCode2() {return 7* Objects.hashCode(name) + 11* Objects.hashCode(phone);}public int hashCode3() {return Objects.hash(name,phone);}}
我们假设当name和phone相同时,则认为这2个对象是equals的。
hashCode()方法是传统的方法,hashCode2()和hashCode3()这2种办法都是JDK7以后支持的,可以简化代码,而且可以避免name为空之类的情形,尤其第3种。
如不需要严格控制hash值,则使用第3种。如要控制hash值,则用第2种。Objects的hash()和hashCode()比较
public class HelloWord{public static void main(String[] args) {System.out.println("a".hashCode());System.out.println(Objects.hashCode("a"));System.out.println(Objects.hash("a"));}}输出结果:97 97 128
由此可见:前两个都是直接计算a的hashCode()编码的,而第三个确实得出不一样的结果.
Objects类中的hash()函数是这样定义的public static int hash(Object... values) {return Arrays.hashCode(values);}
这里调用Arrays类的hashCode()函数
public static int hashCode(Object a[]) {if (a == null){return 0;}int result = 1;for (Object element : a){result = 31 * result + (element == null ? 0 : element.hashCode());}return result;}
4. hashCode和equals的面试题
两个对象 Person p1 p2问题:如果两个对象的哈希值相同 p1.hashCode()==p2.hashCode()两个对象的equals一定返回true吗 p1.equals(p2) 一定是true吗?正确答案:不一定问题:如果两个对象的equals方法返回true,p1.equals(p2)==true两个对象的哈希值一定相同吗正确答案: 一定
在 Java 应用程序执行期间:
1.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
2.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不要求一定生成不同的整数结果。
