集合
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 类型或者其子类类型。
【注意】
集合创建过程中,不允许使用泛型通配符,泛型上限只能明确泛型对应的具体数据类型。