前言
Collection是Java集合框架中List和Set的父类,在学习List和Set之前,我们先研究下Collection的实现
类继承结构
这里以JDK1.8里的AbstractCollection为例
顶层接口为Iterable,Iterable里需要实现的方法只有一个,此方法返回的是一个迭代器,通过迭代器可以遍历集合中的所有元素,不同的集合类实现不同,后面会具体讲解。
Iterator<T> iterator();
看一下Iterator接口的定义:
Iterator接口提供了一种集合遍历的通用方法,Java里所有继承Collection接口的集合类均可通过Iterator进行遍历,关键是通过Iterator进行遍历的同时可以直接删除元素,这是for循环所达不到的效果。
//是否还有更多的元素
boolean hasNext();
//返回迭代器中的下一个元素
E next();
//删除基础集合的最后一个元素,再一次next调用中,remove方法只能被调用一次。如果在迭代进行过程中以其他方式(而不是通过调用此方法)修改了基础集合,那么迭代器的行为就会变得不明确。
void remove();
Collection接口里定义了一个集合的需要实现的基本方法:
//元素个数
int size();
//元素个数是否为0
boolean isEmpty();
//是否存在制定元素o
boolean contains(Object o);
//转化为Object数组
Object[] toArray();
//转化为指定类型(T)数组
<T> T[] toArray(T[] a);
//添加元素,成功返回true
boolean add(E e);
//移除元素,成功返回true
boolean remove(Object o);
//是否包含指定集合中所有元素
boolean containsAll(Collection<?> c);
//将指定集合中所有元素添加到当前集合
boolean addAll(Collection<? extends E> c);
//移除当前集合中所有也存在于指定集合c当中的元素
boolean removeAll(Collection<?> c);
//只保留当前集合中所有也存在于指定集合c中的元素
boolean retainAll(Collection<?> c);
//清除当前集合中所有元素
void clear();
//判断当前元素和指定元素o是否相等
boolean equals(Object o);
//生成hashcode
int hashCode();
关键方法实现
这里仅挑几个常用的方法进行剖析
1.isEmpty()
直接判断size是否为0,一般我们平时工作中不会直接调用这个方法,因为判断一个集合是否为空首先得判断集合引用是否为null,因此实际使用中一般使用第三方CollectionUtils.isEmpty(Collection c)方法进行判空。
public boolean isEmpty() {
return size() == 0;
}
2.boolean contains(Object o)
通过迭代器遍历,入参为null,则判断是否存在null元素,否则通过equals方法比较是否存在相同元素
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
3.boolean remove(Object o)
也是通过迭代器进行遍历,入参为null,则找到null元素,然后删除,否则删除equals为true的元素
public boolean remove(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext()) {
if (it.next()==null) {
it.remove();
return true;
}
}
} else {
while (it.hasNext()) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
}
return false;
}
4.boolean containsAll(Collection<?> c)
for循环遍历指定集合c,然后通过contains方法判断每个元素是否存在于当前集合当中,只有当c中所有元素均存在当前集合,才返回true
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
5.boolean addAll(Collection<? extends E> c)
for循环遍历指定集合c,逐一将c中所有元素添加到当前集合,只要一个元素添加成功,则返回true
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
6.boolean removeAll(Collection<?> c)
通过迭代器遍历当前集合,如果元素也存在于指定集合c中,则删除元素,只要成功删除一个元素,就返回true
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<?> it = iterator();
while (it.hasNext()) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
7.void clear()
通过迭代器遍历当前集合,逐一删除所有元素
public void clear() {
Iterator<E> it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
以上所列举方法为AbstractCollection所实现的且实际工作中比较常用的方法,其余未列举的或者未实现的方法如下:
未实现,需要子类实现的方法:
Iterator iterator();
int size();
boolean add(E e);
实际工作不常用的方法,感兴趣的可以去查看源码:
Object[] toArray();
T[] toArray(T[] a) ;
boolean retainAll(Collection<?> c);