01、集合类简介
Java集合就像一种容器,可以把多个对象(实际上是对象的引用,但习惯上都称对象)“丢进”该容器中。从Java 5 增加了泛型以后,Java集合可以记住容器中对象的数据类型,使得编码更加简洁、健壮。
Java集合大致可以分为两大体系,一个是Collection,另一个是Map
- Collection :主要由List、Set、Queue接口组成,List代表有序、重复的集合;其中Set代表无序、不可重复的集合;Java 5 又增加了Queue体系集合,代表一种队列集合实现。
- Map:则代表具有映射关系的键值对集合。
java.util.Collection下的接口和继承类关系简易结构图:
java.util.Map下的接口和继承类关系简易结构图:
其中,Java 集合框架中主要封装的是典型的数据结构和算法,如动态数组、双向链表、队列、栈、Set、Map 等。
将集合框架挖掘处理,可以分为以下几个部分
1) 数据结构
List列表、Queue队列、Deque双端队列、Set集合、Map映射
2) 比较器
Comparator比较器、Comparable排序接口
3) 算法
Collections常用算法类、Arrays静态数组的排序、查找算法
4) 迭代器
Iterator通用迭代器、ListIterator针对 List 特化的迭代器
02、有序列表(List)
List集合的特点就是存取有序,可以存储重复的元素,可以用下标进行元素的操作
List主要实现类:ArrayList、LinkedList、Vector、Stack。
2.1、ArrayList
ArrayList是一个动态数组结构,支持随机存取,尾部插入删除方便,内部插入删除效率低(因为要移动数组元素);如果内部数组容量不足则自动扩容,因此当数组很大时,效率较低。
2.2、LinkedList
LinkedList是一个双向链表结构,在任意位置插入删除都很方便,但是不支持随机取值,每次都只能从一端开始遍历,直到找到查询的对象,然后返回;不过,它不像 ArrayList 那样需要进行内存拷贝,因此相对来说效率较高,但是因为存在额外的前驱和后继节点指针,因此占用的内存比 ArrayList 多一些。
2.3、Vector
Vector也是一个动态数组结构,一个元老级别的类,早在jdk1.1就引入进来类,之后在jdk1.2里引进ArrayList,ArrayList大部分的方法和Vector比较相似,两者是不同的,Vector是允许同步访问的,Vector中的操作是线程安全的,但是效率低,而ArrayList所有的操作都是异步的,执行效率高,但不安全!
关于Vector,现在用的很少了,因为里面的get、set、add等方法都加了synchronized,所以,执行效率会比较低,如果需要在多线程中使用,可以采用下面语句创建ArrayList对象
List<Object> list =Collections.synchronizedList(new ArrayList<Object>());
也可以考虑使用复制容器 java.util.concurrent.CopyOnWriteArrayList进行操作,例如:
final CopyOnWriteArrayList<Object> cowList = new CopyOnWriteArrayList<String>(Object);
2.4、Stack
Stack是Vector的一个子类,本质也是一个动态数组结构,不同的是,它的数据结构是先进后出,取名叫栈!
关于Stack,现在用的也很少,因为有个ArrayDeque双端队列,可以替代Stack所有的功能,并且执行效率比它高!
03、集(Set)
Set集合的特点:元素不重复,存取无序,无下标;
Set主要实现类:HashSet、LinkedHashSet和TreeSet。
3.1、HashSet
HashSet底层是基于 HashMap 的k实现的,元素不可重复,特性同 HashMap。
3.2、LinkedHashSet
LinkedHashSet底层也是基于 LinkedHashMap 的k实现的,一样元素不可重复,特性同 LinkedHashMap。
3.3、TreeSet
同样的,TreeSet也是基于 TreeMap 的k实现的,同样元素不可重复,特性同 TreeMap;
Set集合的实现,基本都是基于Map中的键做文章,使用Map中键不能重复、无序的特性;所以,我们只需要重点关注Map的实现即可!
04、队列(Queue)
Queue是一个队列集合,队列通常是指“先进先出”(FIFO)的容器。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。通常,队列不允许随机访问队列中的元素。
Queue主要实现类:ArrayDeque、LinkedList、PriorityQueue。
4.1、ArrayDeque
ArrayQueue是一个基于数组实现的双端队列,可以想象,在队列中存在两个指针,一个指向头部,一个指向尾部,因此它具有“FIFO队列”及“栈”的方法特性。
既然是双端队列,那么既可以先进先出,也可以先进后出,以下是测试例子!
先进先出
public static void main(String[] args) { ArrayDeque<String> queue = new ArrayDeque<>(); //入队 queue.offer("AAA"); queue.offer("BBB"); queue.offer("CCC"); System.out.println(queue); //获取但不出队 System.out.println(queue.peek()); System.out.println(queue); //出队 System.out.println(queue.poll()); System.out.println(queue); }
输出结果:
[AAA, BBB, CCC] AAA [AAA, BBB, CCC] AAA [BBB, CCC]
先进后出
public static void main(String[] args) { ArrayDeque<String> stack = new ArrayDeque<>(); //压栈,此时AAA在最下,CCC在最外 stack.push("AAA"); stack.push("BBB"); stack.push("CCC"); System.out.println(stack); //获取最后添加的元素,但不删除 System.out.println(stack.peek()); System.out.println(stack); //弹出最后添加的元素 System.out.println(stack.pop()); System.out.println(stack); }
输出结果:
[CCC, BBB, AAA] CCC [CCC, BBB, AAA] CCC [BBB, AAA]
4.2、LinkedList
LinkedList是List接口的实现类,也是Deque的实现类,底层是一种双向链表的数据结构,在上面咱们也有所介绍,LinkedList可以根据索引来获取元素,增加或删除元素的效率较高,如果查找的话需要遍历整合集合,效率较低,LinkedList同时实现了stack、Queue、PriorityQueue的所有功能。
例子
public static void main(String[] args) { LinkedList<String> ll = new LinkedList<>(); //入队 ll.offer("AAA"); //压栈 ll.push("BBB"); //双端的另一端入队 ll.addFirst("NNN"); ll.forEach(str -> System.out.println("遍历中:" + str)); //获取队头 System.out.println(ll.peekFirst()); //获取队尾 System.out.println(ll.peekLast()); //弹栈 System.out.println(ll.pop()); System.out.println(ll); //双端的后端出列 System.out.println(ll.pollLast()); System.out.println(ll); }
输出结果:
遍历中:NNN 遍历中:BBB 遍历中:AAA NNN AAA NNN [BBB, AAA] AAA [BBB]

