equals 和 hashCode 方法

集合

1. equals 和 hashCode 方法

1.1 equals 方法
equals 方法是在 Object 类内定义的方法。
源码形式:
	/*
	this 表示执行当前方法的类对象,哪一个对象调用该方法,this对应哪一个对象
	*/
	public boolean equals(Object obj) {
        /*
        引用数据类型变量采用 == 比较,仅判断两个引用数据类型变量存储的地址
        是否一致,不判断引用指向内存空间数据内容是否一致,作为判断标准不满足
        一定情况下的需求。
        */
		return this == obj;
	}
需要根据当前代码所需,对 equals 方法进行重写操作。
重写流程:
	1. 判断调用方法对象和参数对象是否为同一个对象。
        调用方法对象和参数对象如果是同地址对象,100%是同一个对象
        if (this == obj) {
            return true;
        }
	2. 参数数据类型是 Object 类型,当前方法允许任何类型作为当前方法参数,如果参数对象真实类型和当前调用方法对象数据类型不一致,没有必要进行比较,或者说直接返回结果 false
        if (null == obj || !obj.getClass().equals(this.getClass())) {
            return false;
        }
	3. 将 Object obj 参数强制为调用方法对象数据类型???
        经历 1 2 两步判断可以保证
        	a. 参数对象和调用方法对象不是同地址对象
            b. 参数对象实际类型和调用方法对象为同一个类型。
        强转没有任何问题!!!
        通过成员变量数据进行等值判断。
@Override
public boolean equals(Object obj) {
	// 1. 判断调用方法对象和参数对象是否为同一个对象。
	if (this == obj) {
		return true;
	}

	// 2. 判断参数对象和调用方法对象是否为同类型对象,不同类型直接返回 false
	if (null == obj || !obj.getClass().equals(this.getClass())) {
		return false;
	}
	
	// 3. 判断参数对象和调用方法对象数据内容
	Person p = (Person) obj;
	
	/*
	 * 在没有明确标明成员变量所属对象,在方法中直接调用成员变量
	 * 默认是调用方法对象对应成员变量数据
	 * id <==> this.id
	 */
	return id == p.id 
			// 同名方法需要明确方法的执行者是谁,到底调用的是哪一个类型方法。当时执行为 String 类型 equals 方法
			&& name.equals(p.name)
			&& age == p.age;
		
}
1.2 hashCode 方法
Java中规定
	两个对象通过 equals 方法比较为同一个对象,要求两个对象的 hashCode 一致。
hashCode方法也是在 Object 类内方法
需要重写 hashCode方法
	根据参与 equals 比较的成员变量数据,利用工具得到对应的哈希值,可以作为 hashCode 方法结果。

工具:
	Objects Object 工具类
	public static int hash(Object... args);
        Object... 要求参数类型为 Object 类型,参数个数不限制!!!
        不定长参数在方法内部执行过程中,实际上是一个数组。
        可以根据参数数据情况,自动生成对应的 hash 值
@Override
public int hashCode() {
    return Objects.hash(id, name, age);
}

2. 泛型上限问题

? 泛型通配符
<?>
<? extends E>
<? super E> 

主要出现在集合中,特指集合操作方法中。
	addAll(Collection<? extends E> c);
	addAll(int index, Collection<? extends E> c);
    removeAll(Collection<?> c);
    retainAll(Collection<?> c);    
    contains(Collection<?> c);
   
错误:
	Collection<?> c = new ArrayList<?>(); 不允许
	Collection<E> c = new ArrayList<E>(); 不允许
    c.add(10);

方法中参数:
	Collection<?> c 
		要求当前方法参数数据类型为 Collection 类型,但是 Collection 存储的数据类型不限制
	Collection<? extends E> c
		要求当前方法参数数据类型为 Collection 类型,同时要求 Collection 中存储的数据类型为调用方法集合存储数据类型,或者其子类类型
		class Animal
		class Dog extends Animal
		class Cat extends Animal
		class Pig extends Animal
		Collection<Animal> c = new ArrayList<Animal>();
		
		c.addAll(Collection<? extends E> c) ==> c.addAll(Collection<? extends Animal> c);
			参数集合必须是 Collection 集合,同时存储数据类型为 Animal 类型或者其子类类型。

【注意】
	集合创建过程中,不允许使用泛型通配符,泛型上限只能明确泛型对应的具体数据类型。
posted @ 2022-05-15 23:48  qtyanan  阅读(64)  评论(0编辑  收藏  举报