十四、集合
1.集合概述
(1)集合是存储其它对象的特殊对象,可以将集合当作一个容器
(2)集合的相关接口和类位于java.util包中
(3)集合中的接口和类是一个整体、一个体系
2.集合接口
接口定义了一组抽象方法,实现该接口的类需要实现这些抽象方法,从而实现接口的类就具备了接口所规定的行为
接口 | 描述 |
Collection | 允许操作一组对象,它位于集合层次结构的顶部 |
List | 扩展Collection,以处理序列 |
Set | 扩展Collection,以处理数组 |
(1)Collection接口
Collection接口是构建集合框架的基础,是泛型接口
interface Collcection<E>
E:集合存储的对象类型
注意:
集合中只能存储对象,不能存储基本类型
接口中没有提供修改元素的方法
优点:在编译时可以检查元素类型,从而更加安全
方 法 | 描 述 |
boolean add(E obj) | 将obj添加到调用集合 |
boolean addAll(Collection<? extends E> c) | 将c中的所有元素添加到调用集合中 |
boolean remove(Object obj) | 从调用集合中删除obj的一个实例 |
boolean removeAll(Collection<?> c) | 从调用集合中删除c的所有元素 |
void clear() | 删除调用集合中的所有元素 |
boolean contains(Object obj) | 如果obj是调用集合的元素,则返回true |
boolean isEmpty() | 如果调用集合为空,则返回true |
int size() | 返回调用集合中元素的数量 |
Iterator<E> iterator() | 返回调用集合的一个迭代器 |
(2)List接口
List接口扩展了Collection,并且声明了存储一连串元素的集合的行为。
在列表中,可以使用从0开始的索引,通过它们的位置插入或访问元素。
方 法 | 描 述 |
void add(int index, E obj) | 将obj插入到index所指定的位置 |
boolean addAll (int index, Collection<?extends E> c) | 将c的所有元素插入到index所指定的位置 |
E remove(int index) | 删除index位置的元素 |
E set(int index, E obj) | 将index所指定位置的元素设置为obj |
E get(int index) | 返回指定索引处存储的对象 |
int indexOf(Object obj) | 返回第一个obj实例的索引 |
int lastIndexOf(Object obj) | 返回列表中最后一个obj实例的索引 |
ListIterator<E> listIterator() | 返回一个迭代器,该迭代器从列表的开头开始 |
List<E>subList(int start,int end) | 返回一个子列表 |
(3)Set接口
Set接口定义了组/集/集合(set),它扩展了Collection接口,并声明了不允许重复元素的集合的行为
注意:
Set接口没有添加自己的方法
SortedSet接口扩展了Set接口,并且声明了以升序进行排序的集合的行为
ortedSet定义了一些便于进行集合处理的方法
NavigableSet接口扩展了SortedSet接口,并且该接口声明了支持基于最接近匹配原则检索元素的集合行为
3.集合类
类 | 描 述 |
ArrayList | 动态数组 |
LinkedList | 链表 |
ArrayDeque | 双端队列 = 队列 + 堆栈 |
PriorityQueue | 支持基于优先级的队列 |
HashSet | 使用哈希表存储元素的组 |
LinkedHashSet | 扩展HashSet类,以允许按照插入的顺序进行迭代 |
TreeSet | 实现存储于树中的集合。 |
(1)ArrayList类
ArrayList实现了List接口。本质上是元素为对象引用的长度可变的数组。
构造方法:
ArrayList( ) :长度取默认值 10
ArrayList(int capacity) :指定长度,容量
泛型:
T :代表一般的任何类
E :代表 Element 元素的意思,或者 Exception 异常的意思
K :代表 Key 的意思
V :代表 Value 的意思,通常与 K 一起配合使用
(2)LinkedList类
LinkedList类实现了List、Deque以及Queue接口,它提供了(双向)链表数据结构
LinkedList具有两个构造方法:
LinkedList( )
LinkedList(Collection<? extends E> c)
ArrayList与LinkedList的区别:
1.ArrayList是基于数组结构的集合,有容量的概念
2.LinkedList是基于链表结构的集合,没有容量的概念
3.对于随机访问(get和set方法),ArrayList优于LinkedList,因为LinkedList要移动指针
4.对于增加和删除操作(add和remove方法),LinkedList比较占优势,因为ArrayList要移动数据,但是如果只是在末尾追加元素,效率差不多
5.LinkedList 还实现了Queue接口,该接口比List提供了更多的方法,包括 offer(),peek(),poll()等
(3)HashSet类
HashSet类实现了Set接口,该类在内部使用哈希表存储元素
哈希表使用称之为散列法(hashing)的机制存储信息,哈希法的优点是add()、contains()、remove()以及size()方法的执行时间保持不变
HashSet中元素不是按有序的顺序存储的,遍历输出HashSet中的元素时精确的输出可能不同
(4)LinkedHashSet类
LinkedHashSet类扩展了HashSet类,它没有添加它自己的方法。
LinkedHashSet在内部使用一个链表维护元素添加到集合中的顺序,因此可以按照插入顺序迭代集合
(5)TreeSet类
TreeSet类实现了NavigableSet接口,该类在内部使用树结构存储元素
元素以升序存储,访问和检索相当快
TreeSet适合于存储大量的、必须能够快速查找到的有序信息
Set与List的区别:
Set中的元素无序不能重复,List中的有序元素可以重复
List有索引(下标)的概念,Set没有索引的概念
对于Set表示的集合,通常是遍历操作,没有get()和set()方法
注意:
1.TreeSet以升序保存对象,所以TreeSet中保存的对象比较能够比较大小,即TreeSet保存的对象类型必须实现Comparable接口
2.HashSet是无序的,LinkedHashSet和TreeSet是有序的
4.集合遍历
Iterable接口是Collection接口的父接口,而所有集合类都实现了Collection接口,从而也都实现了Iterable接口
(1)Iterator接口
Iterator接口描述了迭代器的行为,所有迭代器类都必须实现该接口
方法:
boolean hasNext():如果迭代还有更多的元素则返回true
T next():返回下一个元素
void remove():删除迭代器返回的元素
注意:从Iterator接口定义的方法不难看出Iterator只能从前向后进行遍历
(2)ListIterator接口
Iterator接口有一个子接口ListIterator,ListIterator接口即可以从前向后遍历,也可以从后向前遍历集合,只有实现了List接口的集合类才提供了ListIterator迭代器
List接口提供以下两个方法用于获取列表集合的列表迭代器:
ListIterator<E> listIterator() 该迭代器从列表的开头开始
ListIterator<E> listIterator(int index) 该迭代器从index所指定的位置开始
ListIterator接口定义了以下常用方法:
boolean hasNext()
Boolean hasPrevious()
E next()
int nextIndex()
E previous()
int previousIndex()
(3)使用迭代器
步骤:
1.通过调用集合的Iterator()方法,获取指向集合开头的迭代器
2.建立一个hasNext()调用循环。只要hasNext()返回true,就循环迭代
3.在循环中,通过调用next()获取每个元素
(4)增强for循环
迭代器与增强的for循环之间的区别:
1.使用迭代器遍历集合时,可以调用Iterator.remove()方法删除集合中元素,使用增强的for循环遍历集合时,不能删除集合中的元素
2.可以使用增强的for循环遍历数组,但是数组不支持迭代器
3.使用增强的for循环遍历基本类型的数组时,只能使用数组元素,而不能修改数组元素
5.Collections工具类
Collection提供以下方法对List进行排序操作:
void reverse(List list):反转
void shuffle(List list):随机排序
void sort(List list):按自然排序的升序排序
void sort(List list,Comparator c):定制排序,由Comparator控制排序逻辑
void swap(List list,int i,int j):交换两个索引位置的元素
6.Vector类
现在Vector类实现了动态数组,与ArrayList类似,也实现List接口
Vector与ArrayList的区别:
1.Vector实现同步,线程安全,ArrayList没有实现线程安全
2.Vector性能比ArrayList低
3.Vector和ArrayList在更多元素添加进来时会请求更大的空间,Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%