Collection 及其相关实现的容器简介及用法

2016-02-26 15:35:19   最后更新: 2016-02-26 15:35:19   访问数量:420




大部分语言都提供了容器来解决实际编程中遇到的大量对象的管理功能,例如数组就是最基本的容器,但是数组的大小是固定的,一旦创建不能够再扩展容量,一般情况中,我们需要管理的对象集合大小往往是不固定的

下图展示了 java 容器的相关接口、抽象类、类的继承层次:

 

 

可以看到,图中的容器分为了两大部分:

  1. Collection -- 独立元素序列,List 按照插入顺序保存所有元素,Set 作为键的集合,不能有重复元素,Queue 按照队列规则确定对象顺序
  2. Map -- 键值对,允许通过键来查找值,ArrayList 作为特殊的 Map 使用数字作为键查找对应的值

 

从方法上看,他们都提供了最基本的 toString 方法,使得打印容器非常简单:

package com.techlog.test; import java.util.*; public class Test { public static void main(String[] argv) { Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3)); System.out.println(collection); Map<String, String> map = new HashMap<String, String>(); map.put("hi", "techlog"); map.put("hello", "world"); System.out.println(map); } }

 

打印出了:

[1, 2, 3] {hello=world, hi=techlog}

 

 

由上图可见 Collection 是一个接口,一切序列相关的容器接口和类都实现了 Collection 接口

Collection 接口定义了所有序列容器的公共方法:

Collection 提供的方法
方法名方法说明
addboolean add(E e)添加一个元素到容器中
addAllboolean addAll(Collection c)将另一个容器中的所有元素都添加到该容器中
clearvoid clear()清除所有元素
containsboolean contains(Object o)判断元素是否存在
containsAllboolean containsAll(Collection c)判断容器是否被包含
equalsboolean equals(Object o)调用每个元素的 equals 方法比较两个容器是否相同
hasCodeint hashCode()返回此 collection 的哈希码值
isEmptyboolean isEmpty()返回此 Collection 是否为空
iteratorIterator iterator()返回 Collection 的迭代器对象
removeboolean remove(Object o)删除容器中的某个对象
removeAllboolean removeAll(Collection c)删除两个容器的交集
retainAllboolean retainAll(Collection c)保留两个容器的交集,删除其余元素
sizeint size()返回容器中元素的个数
toArrayObject[] toArray()转换成一个 java 数组
· T[] toArray(T[] a)转换成一个指定类型的泛型数组

 

最常用的序列容器就是 List 了,List 是一个继承了 Collection 接口的接口,他是有序的元素序列容器

ArrayList 和 LinkedList 都是通过实现 List 接口实现的,ArrayList 随机访问的效率很高,但是在列表中间插入和删除操作效率相对较低,LinkedList 则恰恰相反

 

在 Collection 全部接口的基础上提供了以下接口:

List 提供的方法
方法名方法说明
addvoid add(int index, E element)在指定位置插入元素
addAllboolean addAll(int index, Collection c)在指定位置加入指定容器中的全部元素
getE get(int index)获取容器中的元素
indexOfint indexOf(Object o)返回元素在容器中的位置
lastIndexOfint lastIndexOf(Object o)返回元素在容器中最后一次出现的位置
listIteratorListIterator listIterator()返回 List 对应的 ListIterator 对象
·ListIterator listIterator(int index)返回指定索引起始的 ListIterator 对象
removeE remove(int index)删除指定索引的元素
setE set(int index, E element)设置指定元素的值
subListList subList(int fromIndex, int toIndex)返回子序列

 

除此之外,LinkedList 和 ArrayList 都实现了 clone 方法,用来返回容器的副本:Object clone()

 

作为最常用的 List,ArrayList 是在 Object 数组的基础上实现的,因此他在随机访问的场景下具有很强的优势

由于数组的元素数是固定的,因此他提供了设置预置数组大小的方法:void ensureCapacity(int minCapacity),在 ArrayList 初始化时通过设定一个合理且较大的 minCapacity 可以有效提高 ArrayList 初始化速度

 

LinkedList 是通过典型的链表结构实现的,因此在插入删除元素的方面提供了很多方便的操作方法,同时,他还为栈、队列、双端队列的实现提供了方法:

LinkedList 提供的方法
方法名方法说明
addFirstvoid addFirst(E e)在列表起始处插入元素
addLastvoid addLast(E e)在列表最后插入元素
descendingIteratorIterator descendingIterator()返回降序迭代器
elementE element()返回起始元素
getFirstE getFirst()返回起始元素
getLastE getLast()返回末尾元素
offerboolean offer(E e)通过调用 add(e) 实现,添加元素到列表尾部
offerFirstboolean offerFirst(E e)通过 addFirst(e) 实现,添加元素到首部
offerLastboolean offerLast(E e)通过 addLast(e) 实现,添加元素到尾部
peekE peek()返回起始元素
peekFirstE peekFirst()返回起始元素
peekLastE peekLast()返回末尾元素
pollE poll()返回首个元素并删除
pollFirstE pollFirst()返回首个元素并删除
pollLastE pollLast()返回尾部元素并删除
popE pop()返回首个元素并删除
pushvoid push(E e)向首部插入元素
removeFirstE removeFirst()删除首个元素
removeLastE removeLast()删除尾部元素
removeFirstOccurrenceboolean removeFirstOccurrence(Object o)删除首个匹配的对象
removeLastOccurrenceboolean removeLastOccurrence(Object o)删除最后匹配的元素

 

可以看到,LinkedList 提供了查询元素的 get 系列方法和 peek 系列方法,他们的区别是什么呢?如果 get 一个不存在的元素,会抛出一个 java.util.NoSuchElementException 异常,而如果 peek 一个不存在的元素,则会返回 null

 

LinkedList 提供了用来实现 Queue 的方法:

  1. offer -- 插入数据到队列
  2. peek -- 查看数据
  3. poll -- 出队

 

LinkedList 还提供了用来实现 Stack 的方法:

  1. push -- 入栈
  2. pop -- 出栈

 

Set 是一个继承自 Collection 的接口

与 List 不同,Set 并不要求有序,Set 的特点在于他的元素是不会重复的,主要有三种实现:

  1. HashSet -- 使用哈希表结构实现,不保证存储顺序,优势是查询效率高
  2. TreeSet -- 使用红黑树结构实现,按照元素顺序存储
  3. LinkedHashSet -- 继承自 HashSet,结合链表与哈希表结构的复合结构,兼具了查询速度的优势的同时维护了插入顺序

除此之外,他们也都实现了 clone 方法,用来返回容器的副本:Object clone()

 

由于 TreeSet 使用红黑树维护了序列中元素的大小顺序,因此它提供了很多大小相关的操作:

TreeSet 提供的方法
方法名方法说明
ceilingE ceiling(E e)返回大于等于指定元素的最小元素
floorE floor(E e)返回小于等于指定元素的最大元素
lowerE lower(E e)返回小于指定元素的最大元素
higherE higher(E e)返回大于指定元素的最小元素
descendingIteratorIterator descendingIterator()返回降序迭代器
descendingSetNavigableSet descendingSet()返回逆序集合中元素的逆序视图
firstE first()返回首个元素
lastE last()返回末尾元速
headSetSortedSet headSet(E toElement)返回小于toElement的部分视图
·NavigableSet headSet(E toElement, boolean inclusive)返回小于 toElement 的部分视图(如果 inclusive 为 true 则返回小于等于)
tailSetSortedSet tailSet(E fromElement)返回大于 fromElement 的部分视图
·NavigableSet tailSet(E fromElement, boolean inclusive)返回大于 fromElement 的部分视图(如果 inclusive 为 true 则返回大于等于)
pollE poll()返回首个元素并删除
pollFirstE pollFirst()返回首个元素并删除
pollLastE pollLast()返回尾部元素并删除
subSetsubSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)返回元素范围从fromElement到toElement的部分视图(inclusive 为 true 则包含相等元素)
·SortedSet subSet(E fromElement, E toElement)返回元素范围从fromElement到toElement的部分视图

 

Collection 接口声明了 iterator 方法,他要求容器返回一个 Iterator 对象

Iterator 就是迭代器接口,主要用来遍历容器,他有以下方法:

Iterator 提供的方法
方法名方法说明
hasNextboolean hasNext()返回是否是最后一个元素
nextE next()返回下一元素
removevoid remove()删除元素

 

ListIterator 是专门供 List 使用的迭代器,List 接口提供了 listIterator 方法用来返回一个 ListIterator 实例

ListIterator 继承了 Iterator,他在 Iterator 的基础上提供了以下方法:

ListIterator 提供的方法
方法名方法说明
addvoid add(E e)在迭代器位置上添加元素
hasPreviousboolean hasPrevious()是否存在前面一个元素
nextIndexint nextIndex()返回下一个索引值
previousIndexint previousIndex()返回上一个索引值
previousE previous()返回前一个元素
setvoid set(E e)将当前迭代器位置的值设为 e

 

package com.techlog.test; import java.util.*; public class Test { public static void main(String[] argv) { Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3)); for (Integer aCollection : collection) { System.out.print(aCollection + ". "); } } }

 

上面的代码展示了使用迭代器遍历并输出序列中元素的方法及 foreach 的用法

 






技术帖      龙潭书斋      list      java      set      thinking in java      java编程思想      collection      linkedlist      arraylist      hashset      linkedhashset     


京ICP备15018585号