【Java 集合类】Java 集合类总览

jdk 包版本:jdk1.8.0_111

Java标准库自带的java.util包提供了集合类:Collection,它是除Map外所有其他集合类的根接口,它作为一个容器,存储一系列的对象。Map是键值对的结构,存储一系列的键值对<key, value>。Java 的java.util包主要提供了以下四种类型的集合:

  • List:一种有序列表的集合;
  • Set:一种保证没有重复元素的集合;
  • Map:一种通过键值(key-value)查找的映射表集合。
  • Queue:一种队列容器,其特性与List相同,但只能从队头和队尾对元素进行操作。

JDK 为集合的各种操作还提供了两个工具类:CollectionsArrays

在这里插入图片描述

Java集合的设计有几个特点:一是实现了接口和实现类相分离,例如,有序表的接口是List,具体的实现类有ArrayListLinkedList等,二是支持泛型,我们可以限制在一个集合中只能放入同一种数据类型的元素。

Collection之上还继承了Iterable接口,因此 Java 访问集合总是能统一通过迭代器(Iterator)来实现,它最明显的好处在于无需知道集合内部元素是按什么方式存储的。

由于 Java 的集合设计非常久远,中间经历过大规模改进,我们要注意到有一小部分集合类是遗留类,不应该继续使用:

  • Hashtable:一种线程安全的Map实现;
  • Vector:一种线程安全的List实现;
  • Stack:基于Vector实现的LIFO的栈。

还有一小部分接口是遗留接口,也不应该继续使用:

  • Enumeration<E>:已被Iterator<E>取代。

需要特别注意的是,Collection 接口的注释头强调,该接口中的所有方法的实现都没有使用任何并发协议的。也就是,实现该接口的类如果采用默认的实现模式,这个过程是线程不安全的。要想实现线程安全,必须在实现类中重写对应的方法,并且在方法实现逻辑中采用适合的并发策略。

在继承 Collection 接口的基础上,ListSetQueue三大类集合接口根据各自的特点,分别补充了一些新的接口方法,衍生出不同的额外功能,是开发者能够比对各个集合之间的优劣,择优而用。在Collection接口之下,还定义了一个抽象类AbstractColletion对该接口进行实现。根据注释的说明,这个抽象类提供了该接口的一个基础实现,降低了开发者实现该接口需要的工作量。在实现一个继承类时,需要提供 iterator( ) 和 size( ) 方法以及其底层支撑方法的实现;如果具体实现的集合类具备可变性,对应的还要重写增删改相关的方法。

继承AbstractCollection抽象类的抽象类主要有以下三大类集合:

  • AbstractList
  • AbstractSet
  • AbstractQueue

分别对应实现 List,Set,Queue 三大类接口,与 AbstractCollection 类似,这些抽象类为其实现的接口提供了基础的方法实现,简化了继承类实现的开发过程。

List 接口

实现 List 接口的集合类主要包括 Vector,ArrayList,LinkedList 和 AbstractList。其中 Vector 目前已经很少使用,包括其子类 Stack 也基本被弃用,因此在这里不详细讨论。

AbstractList 抽象类

AbstractList 类继承了 AbstractCollection 抽象类,同时实现了 List 接口,为接口内定义的方法提供了基础实现。值得注意的是,开发者继承该抽象类时,不需要再提供迭代器的具体实现,在 AbstractList 内部定义了两个内部类ItrListItr,分别实现了迭代器所需的基本方法。当自定义一个类继承这个抽象类时,通常需要重写一个实现为空的构造方法。

AbstractList 类的内部还定义了两个内部子列表类:SubListRandomAccessSubList。前者定义并且实现了一部分子列表相关的方法;后者继承了前者,并且实现了RandomAccess接口,说明这个类返回的是允许访问随机索引的子列表实例。

AbstractSequenceList 抽象类

AbstractSequenceList 抽象类继承了 AbstractList,在原基础上限制了访问元素的顺序。顾名思义,它不支持随机访问元素,只能按照顺序进行访问。LinkedList使用链表实现,只支持顺序访问,所以继承了AbstractSequenceList抽象类;而像ArrayList这样的类需要支持随机访问,所以继承了AbstractList抽象类。

ArrayList 类

详情请跳转到:https://blog.csdn.net/sinat_36645384/article/details/108537591

LinkedList 类

详情请跳转到:https://blog.csdn.net/sinat_36645384/article/details/108537695

Queue 接口

Queue 队列接口有主要有两种不同的实现:单向队列(AbstractQueue)和双向队列(Deque)。不管是哪种实现,都是基于 Queue 定义的两套接口方法,这两套方法在运行失败时,会有不同的处理策略,具体如下:

插入方法删除方法查找方法失败策略
add()remove()get()抛出异常
offer()poll()peek()返回 false 或者 null

值得注意的是,poll()方法成功运行时,是返回了队列头的元素,并在原队列中删除该元素,而不只是单纯的删除元素。

Deque 接口

Deque 接口继承了 Queue 接口,在原有的基础上增加了具体操作队头和队尾元素的方法。该接口的实现类有两种,分别是LinkedList类和ArrayDeque类,两者的主要区别在于,前者采用链表实现双端队列,而后者使用数组实现双端队列。

LinkedList 类

详情请跳转到:https://blog.csdn.net/sinat_36645384/article/details/108537695

ArrayDeque 类

ArrayDeque 在日常使用不多,它使用数组实现了一个无界的双端队列。它与LinkedList的区别在于,LinkedList采用链表实现双端队列,而ArrayDeque使用数组实现双端队列。它的最小容量为 8,初始化时默认容量为 16,如果初始化时指定一个容量大小的数值,亦或者传入一个集合类,则通过 allocateElements( ) 方法,将初始容量选为比指定容量大的一个最小 2 的幂。

添加新元素时,如果添加后队列已满,也就是head==tail,就会调用内部的 doubleCapacity( ) 方法,重新创建一个数组,容量为原来数组的两倍。如果容量数值通过左移加倍导致越界,那么就会抛出异常。因此需要控制数组的容量不能过大,不能超过 2 32 − 1 2^{32}-1 2321

PriorityQueue 类

详情请跳转到:https://blog.csdn.net/sinat_36645384/article/details/120554718

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值