Java集合框架整理1--Collection体系

Java的集合框架是围绕一组标准接口而设计的接口和类的架构,主要涉及的数据结构为:数组、链表、树、哈希表,在这些基本的数据结构上进行扩展演变而衍生出一系列的功能强大的集合框架。

Java的集合主要分成两大派:Collection系和Map系,Collection体系主要存储单列数据,而Map存储的是<key,value>键值对的数据

Collection体系

 先看下Collection体系主要的接口、类的关系图

Collection体系的顶级接口Iterable接口,Iterable接口是一个迭代器,定义了获取迭代器对象和对内部元素进行迭代的方法

除了最顶层的Iterable接口,Collection体系实际意义上的所有集合的最上层的父接口是Collection接口,Collection接口继承之Iterable接口,在Iterable接口的基础上添加了更多的方法,主要的方法如下:

int size():获取集合的大小

boolean isEmpty():判断集合是否为空

boolean contain(Object o):判断指定元素是否存在于集合内

boolean add(E e):向集合中添加一个元素

boolean remove(Object o):从集合中移除一个元素

void clear():清空整个集合

Object[] toArray():将集合转化为数组

Iterator<E> iterator:遍历集合

1.1、List系列

List系列详细源码解析参见链接: Java集合框架整理3--List系列体系源码解析

1.1.1、List接口

List是存放有序的,可重复的数据结构

List接口继承之Collection接口,除了继承的方法之外,额外增加了List特有的方法,主要有:

default void sort(Comparator<? super E> c):排序方法

E get(int index):获取指定序号的元素

E set(int index, E element):设置指定序号的元素值

void add(int index, E element):在指定的位置插入元素

E remove(int index):删除指定位置的元素

int indexOf(Object o):获取指定元素的第一个序号(指定元素可能在List中存在多个重复的)

int lastIndexOf(Object o):获取指定元素的最后一个序号

List<E> subList(int fromIndex, int toIndex):获取指定区间的子List

可以看出List和Collection最大的区别就是增加了很多和序号index相关操作的方法,因为这也是List最大的特点,那就是每个元素都有一个位置,List可以根据元素的具体位置来很方便的操作

1.1.2、AbstractList抽象类

AbstractList是一个抽象类,位于List接口和ArrayList等具体的List实现类之间的位置,AbstractList的作用是实现类List接口的部分方法,这样既统一了其子类的方法实现,又简化了其子类,给了子类方法提供了默认实现,AbstractList主要实现的方法有:

add(E e)方法:直接调用add(int index, E e),通过size()集合的长度,直接将元素插入该位置(List是有序从尾部插入)

另外还实现了indexOf和lastIndexOf两个获取元素位置的方法

1.1.3、ArrayList类

ArrayList类是继承之AbstractList,并且实现了List接口,从名字就可以看出是以数组为基础的。ArrayList底层就是通过数组来实现的List

ArrayList在进行插入、删除元素时都会执行rangeCheck方法,判断数组是否越界

ArrayList除了实现了List接口,还实现了RandomAccess接口,而RandomAccess接口并没有定义任何方法,所以RandomAccess的作用就是标记的作用,在其他操作的时候就可以判断是否实现了RandomAccess接口来进行不同的操作。而这个操作就是遍历。

ArrayList遍历的时候使用普通的for循环比使用迭代器效率要高,而没有实现RandomAccess接口的LinkedList使用迭代器的效率比for循环要高。因为ArrayList是数组,内存地址是连续的,可以很容易就通过指定位置来找到元素,查询的时间复杂度o(1)

ArrayList查询虽然很快,但是增删是比较慢的,因为会涉及到数组的扩容和元素复制等耗性能等操作,所以ArrayList的使用场景是:顺序插入、频繁查询

1.1.4、LinkedList类

LinkedList类同样是继承之AbstractList,并且实现了List接口,从名字可以看出是以链表为基础的,LinkedList底层就是通过链表来实现的List

LinkedList的元素存储在内部类Node中,Node主要有三个属性,一个item存储数据,next指向下一个节点,prev指向上一个节点,所以LinkedList是一个双向链表

LinkedList的特点是存放的元素之间内存地址不连续,通过next指针来关联,所以可以很容易地实现增加和删除元素。

LinkedList的查询虽然效率没有数组高,但由于是双向链表,也进行了一些优化,根据index进行查询时先判断index是否小于size的一半,如果小于则从头部开始遍历,如果大于,则从尾部开始遍历

但是LinkedList执行和index相关的方法时,性能较差,因为需要从头节点开始不停的遍历才可找到指定位置的元素,所以对LinkedList进行遍历的时候必须是要迭代器,而如果根据for循环来迭代的话,性能会很差。

所以LinkedList的使用场景是:频繁插入删除,而查询较少

1.1.5、Vector类

Vector类同样是继承之AbstractList,并且实现了List,并且和ArrayList一样实现了RandomAccess接口,而底层的实现和ArrayList几乎一样,都是通过数组来实现的

所以用法上基本上和ArrayList一样,只不过Vector的所有方法都加上了Synchronized关键字进行修饰,也就是都加了锁,所以Vector是线程安全的,但是由于加锁,所以效率比ArrayList要差很多

Vector的使用场景是:需要保证线程安全

1.1.6、Stack类

Stack类继承之Vector类,从名字就可以看出Stack是实现类栈的效果,则Vector的基础上添加了入栈push和出栈pop方法,而栈的特点是先进后出,后进先出

所以Stack的入栈方法就是在List的尾部插入元素,出栈方法就是获取List的最后一个元素并返回,同样是线程安全的

Stack的使用场景是:实现栈的效果

1.2、Set系列

Set是存放无序的,不可重复的数据结构

Set系列详细源码解析参见链接: Java集合框架整理4--Set系列体系源码解析

1.2.1、Set接口

Set接口继承之Collection接口,定义的方法都是继承之Collection的,没有额外增加其他方法,因为Set的特点是无序且不重复,所以只需要Set的实现类在进行增删改查数据的方法中达到这个需求即可

1.2.2、SortedSet接口

SortedSet继承之Set,从名字可以看出是排过序的Set,既然Set定义的是无序和不可重复,而List是有序且可重复,那么如果我想要一个既有序又不重复的集合该怎么弄呢,SortedSet就是这种结构的存在

SortedSet既然是接口,所以并没有实现如何排序,而是额外定义了一些方法

headSet():将元素放到集合的头部

tailSet():将元素放到集合的尾部

first():获取集合的第一个元素

last():获取集合的最后一个元素

 1.2.3、NavigableSet接口

 Navigable接口继承之SortedSet,在SortedSet的基础之上额外增加了其他的方法,提供了为指定的搜索目标查询最接近匹配项的导航方法,如:

celling(E e):返回集合中大于等于e的最小元素

floor(E e):返回集合中小于等于e的最大元素

lower(E e):返回集合中小于e的最大元素

pollFirst():获取并移除第一个元素

pollLast():获取并移除最后一个元素

还有其他类似的进行范围比较的获取方法

 1.2.4、TreeSet类

TreeSet类实现了Navigable接口并且继承了AbstractSet抽象类,所以实现了NavigableSet和排序相关的方法

 TreeSet顾名思义是树状结构的Set,是通过二叉树实现的,内部排序方式可以是自定义的Comparator或者是自然排序两种方式

1.2.5、HashSet类

HashSet类继承之AbstractSet抽象类,实现了Set接口

HashSet是无序的,通过哈希表实现,所以查询效率比较高,线程不安全,并且使用HashSet时需要覆盖hashCode方法和equals方法。

原文地址:https://www.cnblogs.com/jackion5/p/10923338.html