(基础)java中的equals与hashcode


hashCode()用于计算该对象的哈希值,当以哈希表为底层数据结构存储数据时,就需要用到哈希值,如HashSet,HashMap等集合容器。

 

hashCode() 与 equals() 为什么要一起重写呢?

通常,是基于这样的考虑:

如果该对象使用哈希表的进行存储,那么需要通过hashCode()计算哈希码,得到对象的地址,当地址相同时,就需要进一步调用该对象的equals()来比较内容是否相同。

因此,才推荐将2个方法一起重写,在使用hash结构的集合存储时,才不会出现问题。

 

自定义哈希值的计算方式---复写hashCode()

 

自定义对象是否相同的比较规则---复写equals()

 

 

 

对象之间的比较,可以比较地址,也可以自定义比较规则

 

==  比较的是对象在内存中的地址是否相同,地址相同,则对象一定相同

 

equals 比较的内容,由equals方法内部指定,可以比较地址(Object基类中的默认实现),也可以自定义比较规则,因此,equals方法提供了对象之间比较的扩展功能。

 

比如,String类复写了Object基类中的equals()

public boolean equals(Object anObject) {
        if (this == anObject) { //先比较地址,如果地址相同,则对象相同
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])//否则,逐一比较字符串中的字符是否相同
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

 

 字符串比较时,使用==与equals()进行比较的区别

public class Test {
	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abc";
		String objStr = new String("abc");
		
		//字符串常量之间的比较,字符串常量在内存中只有一份,因此地址相同,所以都为true
		System.out.println(str1==str2);//true
		System.out.println(str1.equals(str2));//true
		
		//字符串常量与堆内存中字符串的比较
		System.out.println(str1==objStr);//地址不同,false
		System.out.println(str1.equals(objStr));//虽然地址不同,但String类对equals方法进行了扩展,会继续比较字符串中的字符,所以true
	}
	
}

 

 通过复写equals(),自定义对象是否相同的比较规则

public class Person {
	
	private String name;

	public Person() {
		super();
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}


	/**
	 * 自定义Person是否相同的比较规则
	 */
	@Override
	public boolean equals(Object obj) {
		//1.对方是null,直接false
		if(obj == null)
			return false;
		
		//2.类型不同,抛异常
		if(!(obj instanceof Person))
			throw new ClassCastException("类型不同,无法比较");
		
		//3.地址相同,直接true
		if(this == obj)
			return true;
		
		//4.最后,按自定义规则比较。(额外一步:将比较的对象向下转型为同一类型)
		Person anotherPerson = (Person)obj;
		
		//这里又利用了String类中定义的equals(),比较字符串是否相同
		return this.name.equals(anotherPerson.name);
	}
	
	
}

 

 

public class Test {
	public static void main(String[] args) {
		Person p1 = new Person("zs");
		Person p2 = p1;
		Person p3 = new Person("ls");
		Person p4 = new Person("zs");
		
		//对方为null:false
		System.out.println(p1.equals(null));
		
		//地址相同:true
		System.out.println(p1.equals(p2));
		
		//地址不同,内容不同:false
		System.out.println(p1.equals(p3));
		
		//虽然地址不同,但是内容相同:true
		System.out.println(p1.equals(p4));
	}
	
}

 

你可能感兴趣的:(HashCode)