集合
1. 泛型上限问题
? 泛型通配符
<?>
<? 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 类型或者其子类类型。
【注意】
集合创建过程中,不允许使用泛型通配符,泛型上限只能明确泛型对应的具体数据类型。
2. MyArrayList 原码
增
add(E e);
添加在实例化对象过程中约束泛型对应具体数据类型元素对象。
add(int index, E e);
在指定下标位置,添加在实例化对象过程中约束泛型对应具体数据类型元素对象。
删
E remove(int index);
在当前List集合中,删除指定下标元素,返回值是被删除元素对象本身
remove(Object obj);
在当前集合中,删除指定元素
clear();
清空当前集合中所有数据内容
改
E set(int index, E e);
在 List 集合中,使用符合实例化对象过程中约束泛型对应具体数据类型对象,替换指定下标元素,返回值是被替换
元素对象本身
查
int size();
当前集合中有效元素个数
boolean isEmpty();
判断当前集合是否为空
boolean contains(Object obj);
判断参数对象是否在当前集合中存在
Object[] toArray();
返回当前集合中所有元素对象的Object类型数组
E get(int index);
在当前集合中,获取指定下标元素
int indexOf(Object obj);
获取指定元素在当前集合中第一次出现的下标位置
int lastIndexOf(Object obj);
获取指定元素在当前集合中最后一次出现的下标位置
MyArrayList<E> subList(int fromIndex, int toIndex);
从 fromIndex 下标开始,到 toIndex 下标结束,获取子集合对象,要求要头不要尾
3. equals 和 hashCode 方法
3.1 equals 方法
equals 方法是在 Object 类内定义的方法。
源码形式:
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) {
if (this == obj) {
return true;
}
if (null == obj || !obj.getClass().equals(this.getClass())) {
return false;
}
Person p = (Person) obj;
return id == p.id
&& name.equals(p.name)
&& age == p.age;
}
3.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);
}