equals()一般用来比较数据的地址是否相等,针对字符串类型,如此比较没有没有问题,但是在对象之间进行比较,单纯的比较地址就有些问题,比如学生对象,地址相同,但是具体的属性也要进行比较,才能判断是否就是同一个学生
调用从object类继承的equals方法,该方法默认比较两个对象的地址
但是在现实生活中比较两个学生是不是不是同一个人,就不能用比较地址的方法来比较,还要看看具体的属性是否一样,所以需要重写equals()
public class Student extends Object { /** * 学号 */ private int id; /** * 姓名 */ private String name; /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { if (id > 0) { this.id = id; } else { System.out.println("学号不合理!!"); } } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @param id * @param name */ public Student(int id, String name) { super(); this.id = id; this.name = name; } @Override public boolean equals(Object obj) { if (null == obj) { return false; } if (this == obj) { return true; } if (obj instanceof Student) {// 当传输的是我们需要的类型时候,进行强制类型转换 Student student = (Student) obj; if (this.id == student.id && this.name.equals(student.name)) { return true; } else { return false; } } return false; } }
Student student1 = new Student(1001, "qiuxie"); Student student2 = new Student(1002, "zhouxiaomei"); Student student3 = new Student(1001, "qiuxie"); Student student4 = student1; Student student5 = null; Integer integer = 1; System.out.println("student1和student2比较结果:" + student1.equals(student2)); System.out.println("student1和student3比较结果:" + student1.equals(student3)); System.out.println("student1和student4比较结果:" + student1.equals(student4)); System.out.println("student1和student5比较结果:" + student1.equals(student5)); System.out.println("student1和integer比较结果:" + student1.equals(integer));
这里使用instanceof是因为,obj不一定是Student类型,有可能是别的类型
hashCode()返回对象的哈希码值,即内存地址的编号
重写equals()方法,同时也是需要重写hashCode()方法
假如两个对象调用equals方法相等,则调用hashCode方法结果必须相同
假如两个对象调用equals方法不相等,则调用hashCode方法结果应该不相同
为了保证hashCode()和equals方法一致,需要重写hashCode()方法
Student student1 = new Student(1001, "qiuxie"); Student student2 = new Student(1002, "zhouxiaomei"); Student student3 = new Student(1001, "qiuxie"); Student student4 = student1; System.out.println("student1和student2比较结果:" + student1.equals(student2)); System.out.println("student1和student3比较结果:" + student1.equals(student3)); System.out.println("student1和student4比较结果:" + student1.equals(student4)); System.out .println("student1.hashCode()=" + student1.hashCode() + " student2.hashCode()=" + student2.hashCode()); System.out .println("student1.hashCode()=" + student1.hashCode() + " student3.hashCode()=" + student3.hashCode()); System.out .println("student1.hashCode()=" + student1.hashCode() + " student4.hashCode()=" + student4.hashCode());
重写hashCode方法
@Override public int hashCode() { final int type = 12; return type * 31 + getId(); }
保证了equals比较结果相同,hashCode结果相同,重写的方法避免了使用内存地址编号
下面列出基本类型和包装类型的比较
int a = 1; int b = 1; if (a == b) { System.out.println("相等"); } else { System.out.println("不相等"); } Integer cInteger = 2; Integer dInteger = 2; if (cInteger.equals(dInteger)) { System.out.println("包装类型相等"); } else { System.out.println("包装类型不相等"); }
当我们需要把对象的状态信息通过网络进行传输,或者需要将对象的状态信息持久化,以便将来使用时都需要把对象进行序列化
例如:Integer实现了Serializable,所以可以把一个Integer的对象用IO写到文件里,之后再可以从文件里读出,如你开始写入的时候那个对象的intValue() 是5的话,那读出来之后也是5。这一点体现了用序化类的作用,即用来传送类的对象
好处就是自动屏蔽了操作系统的差异