为什么需要容器
容器,顾名思义就是用来存放数据的,但是Java中我们有数组,为什么还需要容器?通常程序总是在运行时才能确定要创建的对象的数量,甚至是对象的类型,为了解决这个问题,Java使用了容器。容器也称为集合类,大致可以分为以下三种:
- Set:集合
- List:列表
- Map:映射
- 工具类:Iterator迭代器、Enumeration枚举类等
容器的类结构图
(图片来自《Think In Java》)
从上图可以很清楚看出,List、Set都是继承自Collection接口,因此下边我们将分别通过Collection和Map来了解容器。
Collection
Collection是最基本的集合接口,Set和List都继承自Collection接口。Collection中主要的方法如下:
boolean add(Object o); //向集合中加入一个对象的引用
void clear() ; //删除集合中所有的对象,即不再持有这些对象的引用
boolean isEmpty(); //判断集合是否为空
boolean contains(Object o); //判断集合中是否持有特定对象的引用
Iterartor iterator(); //返回一个Iterator对象,可以用来遍历集合中的元素
boolean remove(Object o); //从集合中删除一个对象的引用
int size(); //返回集合中元素的数目
Object[] toArray() ; // 返回一个数组,该数组中包括集合中的所有元素
下边我们看看Collection接口下的继承图
List主要以线性方式存储元素,可以存放重复对象,有序存放元素。常用的List有以下几个:
- ArrayList:随机访问元素快,增删元素慢。
- Vector:Vector与ArrayList相似。但Vector的方法是线程安全的,而ArrayList的方法不是,由于线程的同步必然要影响性能,因此ArrayList的性能比Vector好。
- LinkedList:随机访问元素慢,顺序访问快,增删元素快。
- Stack:栈,继承Vector,特点是先进后出(FILO, First In Last Out)
Set不保存重复的元素,Set与Collection有完全一样的接口。Set接口不保证维护元素的次序,即不保证存放有序。常用的实现类有以下几个:
- HashSet : 随机查找快。存入HashSet的对象必须定义hashCode()。HashSet查找某个对象时,首先用hashCode()方法计算出这个对象的Hash码,然后再根据Hash码到相应的存储区域用equals()方法查找,从而提高了效率。
- TreeSet : 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。
- LinkedHashSet : 具有HashSet的查询速度,且内部使用链表维护元素的顺序。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。
Map
首先来看下Map的继承结构
Map是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。常用的Map有以下几个:
- HashMap:Map基于哈希表的 Map 接口的实现。
- HashTable:hashtable和hashmap,从存储结构和实现来讲基本上都是相同的,最大的不同就是hashtable是线程安全的。
- LinkedHashMap: LinkedHashMap是HashMap的一个子类,是Map接口的哈希表和链接列表实现。它维护着一个双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。
- TreeMap : 基于红黑树的实现。
工具类
集合的工具类主要有Iterator迭代器、Enumeration枚举类、Arrays和Collections
Iterator是一个用来遍历并选择序列中的对象,Iterator只能单向移动,其子类ListIterator可以双向,但只能用于各种List的访问。
Enumeration作用于Iterator一样,用来遍历集合,但是功能要比Iterator少,只能在HashTable、Vector和Stack中使用,基本已经被迭代器取代,在实际操作中很少使用。
Arrays能方便地操作数组,它所有的方法都是静态的。
Collections是一个包含各种有关集合操作的静态多态方法的工具类。
参考:https://blog.csdn.net/panweiwei1994/article/details/76618606