Java集合系列01之概览

系列文章

  • Java集合系列01之概览
  • Java集合系列02之ArrayList源码分析
  • Java集合系列03之LinkedList源码分析
  • Java集合系列04之fail-fast机制分析
  • Java集合系列05之Vector&Stack源码分析及List总结
  • Java集合系列06之Map接口概览
  • Java集合系列07之HashMap源码分析
  • Java集合系列08之WeakHashMap源码分析
  • Java集合系列09之TreeMap源码分析
  • Java集合系列10之Hashtable源码分析

前言

从本篇开始,我将开始Java集合系列的梳理,本文先对集合框架中涉及到的接口,架构,类等做一个总体展示,后面的文章中再结合源码分别剖析具体集合,希望能用两个月的时间完成Java集合系列文章。

Java最初版本只为最常用的数据结构提供了很少的一组类:VectorStackHashtableBitSetEnumeration接口。Enumeration接口定义了从一个数据结构得到连续数据的手段,实现了遍历集合,现在已经被迭代器Iterator取代了。JDK1.2版本后,Java开始提供了一组集合框架,完善了Java数据结构。

Java集合包含了以下常用的数据结构:集合(Set,无序不可重合的集合)、列表(List,有序可重复的集合)、队列(Queue,队列集合,JDK1.5后加入)、栈(Stack)、数组、映射表(Map,具有映射关系的集合)等。Java集合类库构成了集合类的框架,包含了大量的接口,抽象类,框架图如下所示:

Java集合系列01之概览_第1张图片
集合框架.png

从上图可以发现,Java集合主要由三个接口派生出来,分别是IteratorCollectionMap,而Collection又派生出ListSetQueue等,可以说是Java集合的根接口了。

迭代器接口(Iterator)

首先我们来看Iterator接口,主要用来遍历集合对象中的元素,其包含三个方法:

public interface Iterator
{
    E next();          // 返回将要访问的下一个对象
    boolean hasNext(); // 如果存在可访问的元素,返回true
    void remove();     // 删除上次访问的对象,必须紧跟在访问一个元素之后执行
}

遍历元素

通过反复调用next方法,可以逐个访问集合中的每个元素,如果到达了集合的末尾,next方法将抛出一个NoSuchElementException,因此在调用next方法之前需要调用hasNext方法判断是否到达集合末尾。使用方法如下:

Collection c = ...
Iterator iter = c.iterator();
while(iter.hasNext())
{
    String ele = iter.next();
    ...
}

Java JDK1.5之后,可以用for循环来执行上述循环操作了,更加简洁,代码如下:

for(String ele : c)
{
    ...
}

编译器将“for each”循环翻译为带有迭代器的循环,“for each”循环适用于任何实现了Iterable接口的对象,Iterable接口只包含了一个方法:

public interface Iterable
{
    Iterator iterator();
}

Collection接口扩展了Iterable接口,因此Java集合中只要实现了Collection集合的接口都可以使用“for each”循环。

删除元素

Iterator接口的remove方法删除上次调用next方法返回的元素,与遍历元素类似,删除某元素前,需要判断该元素是否有意义。正确的使用方法如下:

Collection c = ...
Iterator iter = c.iterator();
iter.next();
iter.remove();

可以看到先调用next方法返回想要删除的元素,再删除之。如果上次访问之后,集合已经发生变化,再调用remove方法,将抛出一个IllegalStateException
以下的使用方法都是错误的:

  • 没有调用next方法
Iterator iter = c.iterator();
iter.remove();
  • 调用一次next方法,删除连续两个元素
Iterator iter = c.iterator();
iter.next();
iter.remove();
iter.remove();

集合接口 (Collection)

方法列表

Collection主要包含了集合的基本操作和属性,有两大分支ListSet。其中定义了很多方法供其子类实现,以实现数据操作,方法列表如下图所示:

Java集合系列01之概览_第2张图片
Collection方法摘要.png

从方法列表中可以看出,Collection接口主要的功能有:添加元素,删除元素,清空集合等。
iterator方法用于返回一个实现了Iterator接口的对象,使用此对象遍历集合元素。

List接口

List是一个元素有序,可重复的集合,每一个元素都有它的索引,可以通过索引来访问指定位置的集合元素。由于List是有序集合,因此List接口中添加了一些根据索引值来操作的方法。List的实现类有LinkedList, ArrayList, Vector, Stack

// List接口与Collection相比新增的方法
abstract void             add(int index, E object)
abstract boolean          addAll(int index, Collection collection)
abstract E                get(int index)
abstract int              indexOf(Object object)
abstract int              lastIndexOf(Object object)
abstract ListIterator  listIterator(int index)
abstract ListIterator  listIterator()
abstract E                remove(int index)
abstract E                set(int index, E object)
abstract List          subList(int start, int end)

Set接口

Set是一个不允许有重复元素的集合,其方法和Collection相比没有区别,当添加重复元素时会返回false,Set的实现类有HashSetTreeSet,而HashSet又依赖于HashMap,实际上是通过HashMap实现的;TreeSet又依赖于TreeMap,实际上是通过TreeMap实现的。

Queue接口

Queue接口模拟了队列这种数据结构,先进先出(FIFO),其方法摘要如下图所示:

Java集合系列01之概览_第3张图片
Queue接口方法摘要.png

Map接口

Map是一个具有映射关系的集合,以“key-value”保存数据。把Map集合里的Key值放在一起就构成了类似于Set的集合,Key值没有顺序,且不允许重复,Map接口的KeySet()方法用于返回Key值构成的Set集合;而把Map集合里的Value值放在一起就构成了类似于List的集合,元素之间可以重复。其方法摘要如下:

Java集合系列01之概览_第4张图片
Map接口方法摘要.png

AbstractCollection类

其定义如下:

public abstract class AbstractCollection extends Object implements Collection {}

AbstractCollection类是一个抽象类,提供了 Collection 接口的大部分实现,以最大限度地减少了实现此接口所需的工作,除了iteratorsize 方法。

要实现一个不可修改的 collection,我们只需扩展此类,并实现 iteratorsize 方法(iterator 方法返回的迭代器必须实现 hasNextnext 方法)。

要实现可修改的 collection,我们必须另外重写此类的 add 方法(否则,会抛出 UnsupportedOperationException),iterator 方法返回的迭代器还必须另外实现其 remove 方法。

AbstractList类

其定义如下:

public abstract class AbstractList extends AbstractCollection implements List {}

AbstractList类是一个抽象类,继承了AbstractCollection类,并实现了List接口,提供了 List 接口的大部分实现,对于连续的访问数据(如链表),应优先继承 AbstractSequentialList,而不是此类。

要实现不可修改的列表,我们只需扩展此类,并提供 get(int)size() 方法的实现。

要实现可修改的列表,我们必须另外重写 set(int, E) 方法(否则将抛出 UnsupportedOperationException)。如果列表为可变大小,则也要重写 add(int, E)remove(int) 方法。

AbstractSet类

其定义如下:

public abstract class AbstractSet extends AbstractCollection implements Set {}

AbstractSet类是一个抽象类,继承了AbstractCollection类,并实现了Set接口,提供了 Set 接口的大部分实现。

工具类及其它接口

ListIterator接口

其定义如下:

public interface ListIterator extends Iterator {}

ListIterator接口继承于Iterator接口,专门用于各种List类型的访问,其方法摘要如下图所示:

Java集合系列01之概览_第5张图片
ListIterator接口方法摘要.png

从上图可以看到,ListIterator接口提供了前向/后向遍历的方法,同时也提供了add()方法,用于添加元素,ListIterator还可以通过nextIndex()previousIndex() 定位当前索引位置。

Arrays

此类包含用来操作数组(比如排序和搜索)的各种方法。主要方法有:

static  List asList(T... a)   // 返回一个受指定数组支持的固定大小的列表。
static int binarySearch(...)        // 二分查找,数组需要有序
static void sort(...)               // 排序
copyOf(...)                         // 复制数组
copyOfRange(...)                    // 复制部分数组

Collections

此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。主要方法有:

static  int binarySearch(...)    // 二分查找
sort(...)                           // 对list集合排序
max(...) / min(...)                 // 对集合取最大值/最小值
static void reverse(List list)   // 反转指定列表中元素的顺序。
static void swap(List list, int i, int j) // 在指定列表的指定位置处交换元素。
....

Arrays和Collections工具类的具体API可以参考JDK文档,此处只列出了一小部分

参考资料

  • Java核心技术卷I
  • Java 集合系列01之 总体框架
  • 由浅入深理解java集合(一)——集合框架 Collection、Map
  • 【深入理解Java集合框架】Java Collections Framework概览

你可能感兴趣的:(Java集合系列01之概览)