今天第一天复习了一下java,和c++中的一些东西类似,子类继承父类需要覆写equals、toString、hashcode方法,这三个方法的作用第一个是比较俩个对象是否相等,只要是它们的成员变量相同就应该返回true,toString将对象转化为一个字符串,和c++中对<<操作符的重载类似,hashcode返回对象的hash码。下面贴上代码看看具体怎么用吧!

//测试类如下
package zaojiahua;

import java.util.HashMap;

public class Extends {
	public static void main(String[] args)
	{
		Student stu1 = new Student("lisi",20);
		Student stu2 = new Student();
		Student stu3 = stu1;
		int i = 5,j = 5;

		//基本数据类型使用==比较的时候比较的是值是否相等
		System.out.println(i == j);
		//引用数据类型使用==比较的时候比较的是是否为堆上同一内存地址
		System.out.println(stu1 == stu2);
		//stu1和stu3指向堆上的同一块内存地址所以返回true
		System.out.println(stu1 == stu3);

		//默认object的equals方法是通过==比较的,所以子类要复写一下
		System.out.println(stu1.equals(stu2));
		System.out.println(stu1.equals(stu3));

		System.out.println(stu1);
		//相当于如下的调用,如果没有覆写toString方法则默认返回的是hashcode
		//System.out.println(stu1.toString());

		//需要导入util包
		HashMap<Student,String> map = new HashMap<Student,String>();
		map.put(stu2, "abc");
		//根据hash值取得value
		System.out.println(map.get(new Student("lisi",23)));

	}
}
package zaojiahua;

public class Student {
	private String name;
	private int age;

	Student()
	{
		this.name = "zhangsan";
		this.age = 20;
	}
	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	//覆写父类的equals方法
	public boolean equals(Object obj)
	{
		//如果它们指向堆上的同一块内存则返回true
		if(this == obj)
			return true;

		//判断obj是否是这个类的对象
		boolean bRet = obj instanceof Student;
		//然后进行比较,如果俩个对象的成员变量的值完全相同的话就返回true
		if(bRet)
		{
			Student stu = (Student)obj;
			if(this.name.equals(stu.name) && this.age == stu.age)
				return true;
			else
				return false;

		}

		return false;
	}

	//覆写父类的toString方法,将任何对象转化为string打印
	public String toString()
	{
		String str = this.name+":"+this.age;
		return str;
	}

	//覆写hashCode方法
	public int hashCode(){
        int result = 11;

        result = 31 * result + age;
        result = 31 * result + name.hashCode();
        return result;
    }

}

下面给出覆写hashCode方法的规则。

1、把某个素数,比如说17,保存在一个叫result 的int 类型的变量值中。

2、对于对象中的每一个关键域f (指equals 方法中考虑的每一个域),完成以下步骤:

  • 为该域计算int 类型的散列码c:按照下面的公式,把步骤a 中计算得到的散列码c 组合到result 中:
    • 如果该域是boolean 类型,则计算(f ? 1 : 0);
    • 如果该域是byte、char、short 或者int 类型,则计算(int)f;
    • 如果该域是long 类型,则计算(int)(f ^ (f >>> 32));
    • 如果该域是float 类型,则计算Float.floatToIntBits(f);
    • 如果该域是double 类型,则计算Double.doubleToLongBits(f) 得到一个long 类型的值,然后按照步骤2.a.iii 对该long 类型计算散列值;
    • 如果该域是一个对象引用,并且该类的equals 方法通过递归调用equals 的方式来比较这个域,则同样对这个域递归调用hashCode 方法;如果要求一个更为复杂的比较,则为这个域计算一个“规范表示”,然后针对这个规范表示调用hashCode。如果这个域的值为null,则返回0;
    • 如果该域是一个数组,则把每一个元素当做单独的域来处理。然后根据步骤2.b 中的做法把这些散列值组合起来。
  • result = 37 * result + c;

3、返回result 值。