新手,刚开始写。如果有没明白可以在下面评论哦,每天晚上下班回家都会在线。对文章结构和叙述请大家给予批评并且给出建议(最重要的一点)
文章中可点击的链接都是我自己写的。
本章主要包括
1 Collection简介
1.1 Collection接口
1.2 AbstractCollection抽象类
2 List简介
2.1 List接口
2.2 AbstractList抽象类
3 Set简介
3.1 Set接口
3.2 AbstractSet抽象类
4 Iterator
5 后续
-
Collection简介
首先我们先来看下Collection的类图
异常庞大的Collection类图
从类图中就可以看出来Collection在Java中有着举足轻重的地位。
将类图放大到Collection的前几个层次你就会发现,Collection主要有两个分支:List和Set。
重要分支
1.1 Collection接口
Collection是集合的高度抽象,定义了集合共有的操作
size():int //返回集合中的元素数量
isEmpty():boolean // 判断集合是否为空
contains(Object):boolean //判断集合是否包含此元素
toArray():Object[] //将集合转化为数组返回
toArray(T[]):T[] //返回指定元素类型的数组
add(E):boolean //添加元素,返回是否添加成功 E为泛型
remove(Object):boolean //删除元素,返回是否删除成功
containsAll(Colleaction<?>):boolean //是否包含此集合
addAll(Colleaction<? extents E>):boolean //添加集合
removeAll(Colleaction<? extents E>):boolean //删除集合
retainAll(Colleaction<?>):boolean //取集合的交集
clear() //清空集合
/** JDK1.8新增,以下方法都用default修饰。
* default模糊了抽象类和接口的关系。用default修饰的方法可以不重写
* 以下方法和特性另开新章节
*/
spliterator():Spliterator<E> //返回可分割迭代器,并发使用.
removeIf(Predicate<? super E>):boolean //指定条件删除
stream():Stream //返回流,相当于高级版的迭代器
parallelStream():Stream //可并行操作的流
containsAll和removeAll的误区
containsAll和removeAll不是删除子集。譬如源Collection是1,2,3待删除的是1,3。那么删除后会为2。
containsAll
removeAll和containsAll类似。
取并集的操作
@Test
public void testRetainAll() {
List<Integer> list = Arrays.asList(1, 2, 3);
List<Integer> retain = Arrays.asList(1, 3);
list.retainAll(retain);
list.forEach(System.out::println);
}
结果为2
请在评论区回答这里为什么是错误的。
1.2 AbstractCollection抽象类
AbstractCollection是对Collection的一些公用方法进行实现。
同时添加了一个常量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
此常量是为了限制数组的长度防止内存溢出
containsAll源码
for (Object e : c)
if (!contains(e))
return false;
return true;
从此出我们可以看出containAll不是判断子集,而是判断是否包含参数集合的所有元素
- List
List继承Colleaction,中文叫做列表,元素可以重复,元素排列有序,线程不安全。
顺序不是指排序而是你添加到时候是3,1,2的顺序添加,那么取出来的顺序也是3,1,2
2.1 List接口
在Collection原有的操作上添加了以下操作
get(int):E //获取索引位置的元素
set(int,E):E //在此索引位置将元素设置为E,也即是替换掉
add(int, E):void //在此索引位置上添加元素E
remove(int):E //删除指定索引位置上的元素并返回此元素
indexOf(Object):int //返回Object在元素上第一次出现的索引位置
lastIndexOf(Object):int //返回Object在元素上最后一次出现的索引位置
listInterator():ListInterator //返回列表迭代器,可以在迭代器中删除元素
listInterator(int): //返回指定开始位置的迭代器
subList(int form,int end): //返回List的视图,从From到end的位置 //在ArrayList一章中会解释,文章发布后会加一个链接
2.2 AbstractList抽象类
AbstractList添加了以下操作和一个变量
removeRange(int from,int end):void //删除from -- end范围内的元素
private rangeCheckForAdd(int):void //判断添加的索引位置是否合法。不合法则抛出IndexOutBoundsException异常
private outOfBoundsMsg(int):String //返回异常的信息,int是非法的索引位置
modCount://变量 记录修改次数,当modCount不匹配的时候会抛出异常。
当然理想很丰满,在单线程的情况下modCount会及时失效。但是在多线程的时候由于内存不可见性会导致modCount的值不是最新值,因此会导致判断不准确。
还有四个内部类
Ltr:从左到右的列表迭代器
ListLtr extends Itr Implement ListIterator:可双向移动的列表迭代器
SubList extends AbstractList:列表试图
RandomAccessSubList extends SubList:可随机访问的列表试图
3 Set
Set继承Collection。中文叫做集合,元素不可以重复,元素排列是无序。
无序的含义是插入时的顺序和取出的顺序不相同,而不是按元素排序。
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(3);
set.add(2);
set.forEach(System.out::println);
输出的结果为1,2,3。自动对元素进行排序。但是不能说它是有序的。
3.1 Set接口
没有增加任何操作
3.2 AstractSet抽象类
AbstractSet继承了AbstractCollection抽象类和Set接口。没有增加操作。
- Iterator
Iterator是集合的迭代器,但是却有限制只能顺序移动。
hasNext():boolean //下一个索引位置是否有元素
next():E //返回下一个位置的元素
remove():void //删除操作。
/**JDK1.8新增*/
forEachRemaining(Consumer<? super E> action):
remove()源码
default void remove() {
throw new UnsupportedOperationException("remove");
}
Iterator使用了迭代器模式。
- 后续
这篇文章会扩展出:迭代器模式,Lambda,ArrayList,SubList,ListIterator等文章。
网友评论