结构图
1. 介绍
- Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类。但却让其被继承产生了两个接口,Set和List。Set不能包含重复的元素。List是有序的集合,可包含重复的元素,提供按索引访问的方式。
- Map是Java.util包中的另一个接口,和Collection接口没有关系,相互独立的,但都属于集合类的一部分。Map包含了key-value。不能包含重复的key,但可包含相同的value。
- Iterator,所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含以下三种方法:
- hasNext()是否还有下一个元素。
- next()返回下一个元素。
- remove()删除当前元素。
2. 几种重要的接口和类简介
- List 接口主要有三个实现类
- LinkedList:基于链表实现,链表内存是散乱的,每个元素存储本身内存地址同时还存储下一个元素的地址。增删快,查找慢;离散存储
- ArrayList:基于数组实现,非线程安全的,效率高便于索引,不便于插入删除;连续存储的
- Vector:基于数组实现,线程安全的,效率低。
- Map 接口主要有三个实现类
- HashMap:基于 hash 表的 Map 接口实现,非线程安全,高效,支持 null 值和 null键;
- HashTable:线程安全,低效,不支持 null 值和 null 键;
2.1. LinkedHashMap:是 HashMap 的一个子类,保存了记录的插入顺序;SortMap 接口: - TreeMap:SortMap 接口的实现类,能够把它保存的记录根据键排序,默认是键值的升序排序。
- Set 接口主要有三个实现类(
- HashSet:底层是由 HashMap 实现,不允许集合中有重复的值,使用该方式时需要重写 equals()和 hashCode()方法;
- LinkedHashSet:继承与 HashSet,同时又基于 LinkedHashMap 来进行实现,底层使用的是 LinkedHashMp)。
- TreeSet实现了SortedSet接口,顾名思义这是一种排序的Set集合,
3. Map
- key-value 的键值对,key 不允许重复,value 可以
- 严格来说并不是一个集合,而是两个集合间的映射关系。
- 这两个集合每一条数据通过映射关系,可看成是一条数据。即 Entry(key,value)。Map 可以看成是由多个 Entry 组成。
- 因Map集合即没实现Collection 接口,也没实现Iterable接口,所以不能对进行 for-each 遍历。
TreeMap和 HashMap 有什么不同点?
- hashMap:哈希表实现。使用HashMap 要求添加的键类明确定义了 hashCode()和 equals()可以重写。hashCode()和 equals(),为了优化 HashMap 空间的使用,可调优初始容量和负载因子。
- TreeMap:基于红黑树实现。TreeMap 没有调优选项,因为该树总处于平衡状态。
- HashMap 通过 hashcode 对其内容进行快速查找。
- TreeMap 中所有的元素都保持着某种固定的顺序,如需得到一个有序的结果就该使用 TreeMap(HashMap 中元素的排列顺序是不固定的)。
- HashMap 非线程安全
TreeMap 线程安全 - HashMap:适用于在 Map 中插入、删除和定位元素。
Treemap:适用于按自然顺序或自定义顺序遍历键(key)。 - 总结:HashMap通常比 TreeMap 快一点(树和哈希表的数据结构使然),建议多使用HashMap,需排序的Map时候才用 TreeMap
3.1. Map 和 Set 集合的关系
- 都有几个类型的集合。HashMap 和 HashSet ,都采用哈希表算法;TreeMap 和 TreeSet 都采用 红-黑树算法;LinkedHashMap 和 LinkedHashSet 都采用哈希表算法和红-黑树算法。
- 分析 Set 的底层源码这里写图片描述,Set 集合 就是 由 Map 集合的 Key 组成。
3. SET架构
- Set 继承于Collection的接口。不允许有重复元素的集合。
- HashSet:不能保证元素的顺序;不可重复;不是线程安全的;集合元素可以为 NULL;
- 底层是一个数组,意义是加快查询速度。一般数组中元素在数组中的索引位置是随机的,元素取值和元素位置间不存在确定关系,在数组中查找特定值时,要把查找值和一系列元素进行比较,查询效率依赖于查找过程中比较的次数。而HashSet 集合底层数组的索引和值有一个确定关系:index=hash(value),只需调这个公式,就能快速找到元素或索引。
- 对于 HashSet: 如两个对象通过equals() 方法返回true,两对象的hashCode值也相同。
当向HashSet集合中存入一个元素时,HashSet会先调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据hashCode值决定该对象在HashSet中的存储位置
- hashCode 值不同,直接把该元素存储到 hashCode() 指定的位置
- hashCode 值相同,那么会继续判断该元素和集合对象的 equals() 作比较
- hashCode 相同,equals 为 true,则视为同一个对象,不保存在 hashSet()中
- hashCode 相同,equals 为 false,则存储在之前对象同槽位的链表上,非常麻烦,应约束这种情况,即保证:如果两个对象通过 equals() 方法返回 true,这两个对象的 hashCode 值也应该相同。
- 注意:每个存储到哈希表中的对象,都得提供 hashCode() 和 equals() 方法的实现,用来判断是否是同一个对象
对于 HashSet 集合,要保证如两对象通过 equals()返回 true,两对象的hashCode 值也应相同
- AbstractSet 是抽象类,继承AbstractCollection。AbstractCollection实现了Set中绝大部分函数,为Set的实现类提供了便利。
- HastSet 和 TreeSet 是Set的两个实现类。
- HashSet依赖于HashMap,实际上是通过HashMap实现。HashSet中的元素无序的。
- TreeSet依赖于TreeMap,它实际上是通过TreeMap实现。TreeSet中的元素有序的。
- LinkedHashSet继承于HashSet,是具有可预知迭代顺序的Set 接口的哈希表和链接列表实现。此实现与HashSet 的不同在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。
4. 面试题
下列说法正确的是()
A. LinkedList继承自List
B. AbstractSet继承自Set
C. HashSet继承自AbstractSet
D. WeakMap继承自HashMap
- List,Set,Map在java.util包下都是接口
- List有两个实现类:ArrayList和LinkedList
- Set有两个实现类:HashSet和LinkedHashSet
- AbstractSet实现了Set
正确说法如下:
A:LinkedList实现了List接口;
B: AbstractSet实现了Set接口;
C: HashSet继承自AbstractSet基类;
D: WeakMap继承自 AbstractMap
5. 迭代器
Iterator:迭代器,Java集合顶层接口(不包括map系列集合,Map接口是map系列集合顶层接口)
- Object next():返回迭代器刚越过的元素的引用,返回值是 Object,需要强制转换成自己需要的类型
- boolean hasNext():判断容器内是否还有可供访问的元素
- void remove():删除迭代器刚越过的元素