(4)java数据结构--集合类及其数据结构归纳-有大图

时间:2021-08-24 08:40:29

Java集合类及其数据结构归纳 - s小小的我 - 博客园
http://www.cnblogs.com/shidejia/p/6433788.html

---------大图可以 在新标签中打开图片 看到大图

(4)java数据结构--集合类及其数据结构归纳-有大图

上面这张图总结了java集合类的继承结构,下面是对集合类的一些总结和特性描述:

Collection

Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作:添加、删除、清空、遍历、是否为空、获取大小、是否保护某元素等等。
Collection接口的所有子类(直接子类和间接子类)都必须实现2种构造函数:不带参数的构造函数和参数为Collection的构造函数。带参数的构造函数,可以用来转换Collection的类型。

AbstractCollection

AbstractCollection是一个抽象类,它实现了Collection中除iterator()和size()之外的函数。由于它实现了Collection接口中的大部分函数,从而方便其它类实现Collection,比如ArrayList、LinkedList等,它们这些类想要实现Collection接口,通过继承AbstractCollection就已经实现了大部分的接口了。

List

List是一个继承于Collection的接口。

List是有序的队列,List中的每一个元素都有一个索引。第一个元素的索引值是0,往后的元素的索引值依次+1。

和Set不同,List中允许有重复的元素。

既然List是继承于Collection接口,它包含了Collection中的全部函数接口;由于List是有序队列,它也额外的有自己的API接口。主要有“添加、删除、获取、修改指定位置的元素”、“获取List中的子队列”等。

List中有listIterator()方法,List的实现类都要实现listIterator()方法,返回一个ListIterator对象。

ListIterator是一个继承于Iterator的接口,它是队列迭代器。专门用于便利List,能提供向前/向后遍历。相比于Iterator,它新增了添加、是否存在上一个元素、获取上一个元素等等API接口。

AbstractList

AbstractList是一个继承于AbstractCollection,并且实现List接口的抽象类。

它实现了List中除size()、get(int
location)之外的函数。由于它实现了List接口中的大部分函数,从而方便其它类继承List。AbstractList和AbstractCollection相比,AbstractList抽象类中实现了iterator()接口。

ArrayList

ArrayList继承了AbstractList抽象类,实现了List接口。

它是一个数组队列,相当于动态数组。与Java中的数组相比,它的容量能动态增长。

ArrayList还实现了RandomAccess(提供了随机访问功能:即可以通过元素的序号快速获取元素对象),
Cloneable(能被克隆), java.io.Serializable(支持序列化,能通过序列化去传输)这些接口。

ArrayList中是非线程安全的,所以在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。

LinkedList

LinkedList
是一个继承于AbstractSequentialList的双向链表,可以被当作堆栈、队列或双端队列进行操作。

LinkedList同时还实现了List、Deque(双端队列)、Cloneable(能克隆)、java.io.Serializable(支持序列化,能通过序列化去传输)等接口。LinkedList是非同步的。

Vector

Vector
是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List(支持相关的添加、删除、修改、遍历等),
RandomAccess(随机访问功能), Cloneable(能被克隆)这些接口。

Vector实际上是通过一个数组去保存数据的。当我们构造Vecotr时;若使用默认构造函数,则Vector的默认容量大小是10。

当Vector容量不足以容纳全部元素时,Vector的容量会增加。若容量增加系数
>0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。

Vector的克隆函数,即是将全部元素克隆到一个数组中。和ArrayList不同,Vector中的操作是线程安全的。

Stack

Stack是栈。它的特性是:先进后出(FILO, First In Last Out)。

Stack继承于Vector(矢量队列)的,由于Vector是通过数组实现的,这就意味着,Stack也是通过数组实现的,而非链表。

Set

Set是一个继承于Collection的接口。Set是没有重复元素的集合。

AbstractSet

AbstractSet是一个继承于AbstractCollection,并且实现Set接口的抽象类。它实现了Set接口中的大部分函数,从而方便其它类实现Set接口。

HashSet

HashSet
是一个没有重复元素的集合,继承于AbstractSet,并且实现了Set接口。

它是由HashMap实现的,HashSet中含有一个HashMap类型的成员变量map,HashSet的操作函数,实际上都是通过map实现的。HashMap不保证元素的顺序,而且HashSet允许使用
null 元素。HashSet是非同步的。

TreeSet

TreeSet是一个有序的集合,它是通过TreeMap实现的,TreeSet中含有一个NavigableMap类型的成员变量m,而m实际上是TreeMap的实例。

TreeMap继承于AbstractSet(具有Set的属性和方法)抽象类,实现了NavigableSet(支持一系列的导航方法,比如查找与指定目标最匹配项),
Cloneable(能被克隆),
java.io.Serializable(支持序列化,能通过序列化去传输。当写入到输出流时,依次写入“比较器、容量、全部元素”;当读出输入流时,再依次读取。)接口。

TreeSet是基于TreeMap实现的。TreeSet中的元素支持2种排序方式:自然排序或者根据创建TreeSet时提供的Comparator进行排序。这取决于使用的构造方法。

TreeSet为基本操作(add、remove 和 contains)提供受保证的 log(n)
时间开销。

TreeSet是非同步的,即非线程安全的。 它的iterator
方法返回的迭代器是fail-fast的。

Map

Map是一个键值对(key-value)映射接口。Map映射中不能包含重复的键;每个键最多只能映射到一个值。

Map提供接口分别用于返回键集、值集或键-值映射关系集:

  entrySet()用于返回键-值集的Set集合;

  keySet()用于返回键集的Set集合;

  values()用户返回值集的Collection集合。

因为Map中不能包含重复的键;每个键最多只能映射到一个值。所以,键-值集、键集都是Set,值集时Collection。

Map提供了“键-值对”、“根据键获取值”、“删除键”、“获取容量大小”等方法。

AbstractMap

AbstractMap类提供Map接口的骨干实现,以最大限度地减少实现此接口所需的工作。

SortedMap

SortedMap是一个继承于Map接口的接口。它是一个有序的SortedMap键值映射。

SortedMap的排序方式有两种:自然排序或者用户指定比较器。插入有序
SortedMap的所有元素都必须实现Comparable接口(或者被指定的比较器所接受)。

NavigableMap

NavigableMap是继承于SortedMap的接口。它是一个可导航的键-值对集合,具有了为给定搜索目标报告最接近匹配项的导航方法。

NavigableMap分别提供了获取“键”、“键-值对”、“键集”、“键-值对集”的相关方法。

HashMap

HashMap是一个散列表,它存储的内容是键值对(key-value)映射。

HashMap继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。

HashMap的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。

TreeMap

TreeMap实现SortedMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator
遍历TreeMap时,得到的记录是排过序的。

TreeMap基于红黑树(Red-Black
tree)实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。

Hashtable

Hashtable与HashMap类似,Hashtable继承自Dictionary类,实现了Map接口,不同的是它不允许记录的键或者值为空;和HashMap相比,Hashtable是线程同步的,即任一时刻只有一个线程能写Hashtable,因此也导致了
Hashtable在写入时会比较慢。而且Hashtable可以通过Enumeration去遍历。

LinkedHashMap

LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的。也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。

Enumeration和Iterator比较:

(01) 函数接口不同

Enumeration只有2个函数接口。通过Enumeration,我们只能读取集合的数据,而不能对数据进行修改。

Iterator只有3个函数接口。Iterator除了能读取集合的数据之外,也能数据进行删除操作。

(02) Iterator支持fail-fast机制,而Enumeration不支持。

Enumeration 是JDK
1.0添加的接口。使用到它的函数包括Vector、Hashtable等类,这些类都是JDK
1.0中加入的,Enumeration存在的目的就是为它们提供遍历接口。Enumeration本身并没有支持同步,而在Vector、Hashtable实现Enumeration时,添加了同步。

而Iterator 是JDK
1.2才添加的接口,它也是为了HashMap、ArrayList等集合提供遍历接口。Iterator是支持fail-fast机制的:当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。