Java集合系列01之概览

系列文章

前言

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

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

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

集合框架.png

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

迭代器接口(Iterator)

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

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

遍历元素

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

Collection<String> c = ...
Iterator<String> 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<E>
{
    Iterator<E> iterator();
}

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

删除元素

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

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

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

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

集合接口 (Collection)

方法列表

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

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<? extends E> collection)
abstract E                get(int index)
abstract int              indexOf(Object object)
abstract int              lastIndexOf(Object object)
abstract ListIterator<E>  listIterator(int index)
abstract ListIterator<E>  listIterator()
abstract E                remove(int index)
abstract E                set(int index, E object)
abstract List<E>          subList(int start, int end)

Set接口

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

Queue接口

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

Queue接口方法摘要.png

Map接口

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

Map接口方法摘要.png

AbstractCollection类

其定义如下:

public abstract class AbstractCollection<E> extends Object implements Collection<E> {}

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

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

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

AbstractList类

其定义如下:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}

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

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

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

AbstractSet类

其定义如下:

public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {}

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

工具类及其它接口

ListIterator接口

其定义如下:

public interface ListIterator<E> extends Iterator<E> {}

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

ListIterator接口方法摘要.png

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

Arrays

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

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

Collections

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

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

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

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342