Java SE(7)-集合框架
Collection
内存层面需要针对多个数据进行存储,可以考虑的容器有:数组、集合类。
数组初始化后的长度不可变,存储数据为单一类型,可包含重复元素,不适用于不可重复的场景;可用的属性和方法都极少;不便删除和插入元素。
Java中的集合框架(Java Collections Framework,简称JCF)是一个 统一的架构,用于表示和操作一组对象。
Java集合框架体系:
java.util.Collection
:存储一个一个的数据- 子接口:List,存储有序的、可重复的数据(动态数组)
ArrayList
,LinkedList
,Vector
- 子接口:Set,存储无序的、不可重复的数据(类似集合)
HashSet
,LinkedHashSet
,TreeSet
- 子接口:List,存储有序的、可重复的数据(动态数组)
java.util.Map
:存储一对一对的数据HashMap
,LinkedHashMap
,TreeMap
,Hashtable
,Properties
ArrayList
创建模板:Collection coll = new ArrayList();
使用xxx.add(Object e)
添加对象(向Collection中添加元素的时候要重写equals)。
特性 | ArrayList | 普通数组 (Array[]) |
---|---|---|
长度 | 动态变化,可自动扩容 | 固定长度,创建后不可更改 |
添加元素 | 使用 add() 方法添加 |
需指定索引或使用循环添加 |
删除元素 | 使用 remove() 方法删除 |
不支持直接删除,需要移动元素 |
查找元素 | 使用 get(index) 获取元素 |
使用 array[index] 访问 |
是否支持泛型 | 支持,例如 ArrayList<Integer> |
不支持泛型 |
是否支持基本类型 | 不支持,只能存对象(可装箱) | 支持基本类型和对象类型 |
是否线程安全 | 默认不是线程安全的 | 不是线程安全 |
使用场景 | 元素数量不确定、操作灵活 | 元素数量固定、结构简单 |
迭代器
Iterator,获取迭代器的对象:Iterator itr = 集合.iterator();
遍历集合的所有元素:itr.hasNext()
+itr.next()

增强for循环
作用:遍历数组,集合
集合:底层使用迭代器
1 |
|
List及其实现类的特点
List存储有序的可重复的数据,动态数组,每增加一个对象容量就自动加一。
- ArrayList:List的主要实现类,底层使用Object[]数组存储,插入和删除数据时效率低
- LinkedList:底层使用双向链表的方式存储,添加和查找数据时效率较低。适用于对集合中的数据进行频繁的删除和插入操作.
- Vector:古老,不用
Collection、List、ArrayList的对比:
特性 | Collection | List | ArrayList |
---|---|---|---|
类型 | 接口 | 接口(继承自 Collection) | 类(实现了 List 接口) |
是否可实例化 | ❌ 不能直接实例化 | ❌ 不能直接实例化 | ✅ 可以直接实例化 |
顺序性 | ❌ 不保证顺序(由子接口决定) | ✅ 保证元素顺序 | ✅ 保证元素顺序 |
是否允许重复 | ❓ 由具体实现决定 | ✅ 允许重复元素 | ✅ 允许重复元素 |
随机访问效率 | ❌ 无此功能 | ✅ 有 get(int) 方法 |
✅ 快速随机访问(基于数组) |
常见实现类 | List、Set、Queue 等 | ArrayList、LinkedList 等 | 自身是实现类 |
典型使用场景 | 操作所有集合的通用方法 | 操作有序集合(如列表) | 频繁查询、随机访问 |
方法示例 | add() , remove() , size() |
加上 get() , set() ,
indexOf() 等 |
同 List,同时还有优化的内部实现 |
Set
存储无序的不可重复的数据。
HashSet
:主要实现类,底层使用HashMap
,即数组+单向链表+红黑树LinkedHashSet
:HashSet
的子类;在现有的结构的基础上又添加了一组双向链表,用于记录添加元素的先后顺序,便于频繁的查询操作。
TreeSet
:底层使用红黑树存储。可以按照添加元素的指定的属性大小顺序进行遍历。
常用方法即Collection
中常用的方法,无新增方法。
- 使用频率:相较于List和Map来说Set使用的频率较小。
- 用来过滤重复数据。
无序性:添加的元素的存储顺序并非依次紧密排列,使用哈希算法。如果想保留添加元素的顺序,就用LinkedHashSet
;如果希望自动排序,就用TreeSet
。
添加到HashSet/LinkedHashSet中的元素的要求:元素所在的类要重写两个方法:equal()
和hashCode()
。比较的标准:哈希值和equals得到的布尔型变量的值。
HashSet
用于去重
TreeSet
底层:红黑树。可以按照指定的大小顺序自动排序。
- 要求TreeSet中的元素必须是同一个类型,否则类型转换错误。
- 处理对象比较方法,排序的标准就是自然排序或定制排序对应方法的返回值。如果是零则认为是相等,不添加新元素。
- 不需要重写
hashCode()
和equals()
方法。
Map
Map及其实现类对比
java.util.Map
:存储一对一对的键值对.
1 |
|
特性 | HashMap | LinkedHashMap | TreeMap | Hashtable | Properties |
---|---|---|---|---|---|
所属接口 | Map | Map | Map, SortedMap, NavigableMap | Map | Hashtable |
是否线程安全 | 否 | 否 | 否 | 是 | 是 |
是否允许 null 键 | 是(最多一个) | 是(最多一个) | 否(键不能为 null) | 否 | 否 |
是否有序 | 否 | 有插入顺序 | 有自然顺序或指定 Comparator | 否 | 否 |
底层结构 | 哈希表 | 哈希表 + 双向链表 | 红黑树 | 哈希表 | 哈希表 |
性能 | 查询快,一般推荐 | 查询快,顺序操作性能略低 | 查询较慢,适合排序需求 | 查询快,但并发性能不佳 | 主要用于配置文件加载 |
用途 | 通用 Map 容器 | 保留插入顺序的 Map | 需要排序的 Map | 早期线程安全 Map,已过时 | 存储配置信息(key/value 字符串) |
HashMap
HashSet
就是基于HashMap
实现的。两者的对比如下:
特性 | HashSet |
HashMap |
---|---|---|
存储结构 | 只存储元素(作为键) | 存储键值对(key-value) |
是否允许重复 | ❌ 不允许重复元素 | ✅ 键不允许重复,值可以重复 |
内部实现 | 基于 HashMap 实现 |
使用数组+链表(或红黑树)实现 |
查找效率 | O(1) | O(1) |
底层结构 | 实际是 HashMap<E, Object> |
实际是 HashMap<K, V> |
HashSet
中只存储元素(值),而不是键值对。
为了实现这一点,它把元素作为HashMap
的键,用一个统一的对象(比如PRESENT
)作为值。
所以其实每次你往HashSet
添加一个元素时,它是在底层的HashMap
中添加了一条键值对:
map.put(element, PRESENT);
- HashMap中的key用Set来存放,无序而且不允许重复,所以同一个Map对象所对应的类需要重写hashCode和equals。
- HashMap中的Value可重复、无序。不强制重写任何方法。
hashCode():如果两个键的哈希值不同,那么肯定不是相同的键。如果相同,不一定相等,还要靠equals()再判断一次。
equals():二次判断
- 每一个键值对构成一个entry,所有的entry构成了一个Set集合
基本操作:
- 增:put(Object key,Object value) putAll(Map m)
- 删:Object remove(Object key)
- 改:put(Object key,Object value)返回值为旧数据,覆盖。putAll
- 查:Object get(Object key)
- 长度:size()
- 遍历:Set keySet(),Collection values(),Set entrySet()
TreeMap
- 底层使用红黑树,按照key指定的大小顺序排序。
- 需要考虑使用对象排序
- 必须是同一个类型的对象
Properties
- Hashtable的子类
- 键和值都是String类型,用来处理属性文件
Collections工具类
Collection
是集合框架中的存储一个一个元素的接口,又分为List和Set等子接口。
Collections
是一个操作Set,List,Map等集合的工具类。