目录
Java 集合类分为两个分支Collection与Map,集合类框架如下图所示:
1 Collection根接口
collection是集合类的根接口,其实现Iterable迭代器接口,所以其所有实现类都可通过迭代器遍历集合内元素。collection下有Set,Queue,List 三个子接口。每个接口的特性如下:
- List集合为元素存取有序的集合,该接口的实现类可以精确的操作集合的每个元素,集合可以包含重复元素;
- Set集合不允许包含相同的元素,而判断两个对象是否相同则是根据equals方法。
- Queue用于模拟队列这种数据结构,遵循先进先出原则。通常只是对集合的首尾进行操作,并不对集合内部进行操作
collection的集合架构图如下:
2 Collection 集合的遍历
- 由于Collection 集合实现了Iterable迭代器接口,所以可以使用迭代器对集合元素进行遍历。
- 可以使用foreach进行集合遍历,增强for底层用的也是Iterator迭代器;
- 使用普通for循环
注意:当集合使用迭代器进行遍历时,要想在遍历过程中删除元素,只能使用iterator.remove()方法,不能使用集合list的remove方法,否者会导致 ConcurrentModificationException。iterator.remove()方法从底层集合删除迭代器上一次执行next方法时返回的元素。next方法之后只能调用remove方法一次,否则会导致异常。
3 List 集合
3.1 ArrayList与LinkedList的区别:
- ArrayList是一个泛型类,底层采用可调整大小的数组实现,通过索引可以对元素进行快速随机访问,所以时间复杂度是O(1)的。但在向数组中间进行插入,删除操作时,由于要进行索引移动,所以增删慢,其时间复杂度是O(n)的;LinkedList是一个泛型类,底层是一个双向链表,其在头部的添加,删除操作只需改变指针指向即可,其时间复杂度是O(1)的。在中间的删除以及添加也需要先进性查找,所以时间复杂度是O(n)的。当进行查询操作时,需要移动指针从前往后依次查找,所以所以时间复杂度是O(n)的。
-
ArrayList实现RandomAccess接口,而LinkedList没实现。RandomAccess接口是一个标记接口,用以标记实现的List集合具备快速随机访问的能力。由于ArrayList基于数组实现,天然带下标,可以实现常量级的随机访问,复杂度为O(1),而LinkedList基于链表实现,随机访问需要依靠遍历实现,复杂度为O(n)。所以ArrayList具备快速随机访问功能,而LinkedList没有。当一个List拥有快速访问功能时,其遍历方法采用for循环最快速。而没有快速访问功能的List,遍历的时候采用Iterator迭代器最快速。当我们不明确获取到的是Arraylist,还是LinkedList的时候,我们可以通过RandomAccess来判断其是否支持快速随机访问,若支持则采用for循环遍历,否则采用迭代器遍历。可以采用 instanceof 关键字来判断类是否具备快速随机访问功能。