List,Set和Map详解
本篇参考Java集合中List,Set以及Map等集合体系详解(史上最全),Set、List、Map的区别与联系,及面试重点问题两位博主写的写博文。我的这篇只是对其稍加整合了。
Java集合三大类
Java中的集合包括三大类:Set(集)、List(列表)和Map(映射),它们都处于java.util包中,Set、List和Map都是接口,它们有各自的实现类。Set的实现类主要有HashSet和TreeSet,List的实现类主要有ArrayList,Map的实现类主要有HashMap和TreeMap。
Collection是最基本的集合接口,声明了适用于JAVA集合的通用方法,List 和 Set都继承自collection接口。
List
- 允许重复的对象。
- 可以插入多个null元素。
- 是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
- 常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。
Set
- 不允许重复对象
- 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
- 只允许一个 null 元素
- Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。
Map
- Map不是collection的子接口或者实现类。Map是一个接口。
- Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。
- TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。
- Map 里你可以拥有随意个null 值但最多只能有一个l nul键。
- Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)
List,Set和Map的区别
Set集合中的对象不按特定方式排序,并且没有重复对象。排序方式有默认排序和定制排序,定制排序需要实现Comparator接口。
List集合中的对象按索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象。
Map集合中的元素都包含 一对键对象和值对象,键对象不可以重复,值对象可以重复。
List,Set和Map的联系和使用场景
ArrayList、Vector和LinkedList的区别
List 有序,可重复 | 区别和联系 |
---|---|
ArrayList | 底层数据结构是数组,查询快,增删慢,线程不安全,效率高。当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间 |
Vector | 底层数据结构是数组,查询快,增删慢,Vector的方法都是同步的(Synchronized),是线程安全的,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好 |
LinkedList | 底层数据结构是链表,查询慢,增删快,线程不安全,效率高 |
ArrayList和LinkedList的使用场景
- 若经常使用索引对容器中的元素进行访问,那么使用List 。如果知道索引,那么 List 的实现类比如 ArrayList 可以提供更快速的访问,因为LinkedList要移动指针。如果经常添加、删除元素的,选LinkedList。
- 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
- ArrayList是基于数组的,LinkedList是基于链表的。
HashSet、LinkedHashSet和TreeSet的区别
Set 无序,唯一 | |
---|---|
HashSet | 底层数据结构是哈希表(数据无序,唯一) 可以放入null,但只能放入一个null,两者中的值都不能重复,如数据库中唯一约束 依赖两个方法:hashCode()和equals()来保证元素的唯一性 只是通用的存储数据的集合 |
LinkedHashSet | 底层数据结构是链表和哈希表。(FIFO插入有序,唯一) 由链表保证元素有序 由哈希表保证元素唯一 用于保证FIFO即有序的集合(先进先出) |
TreeSet | 底层数据结构是红黑树。(唯一,有序) Treeset中的数据是自动排好序的,不允许放入null值。 通过自然排序和比较器排序保证元素有序 根据比较的返回值是否是0来决定来保证元素唯一性 主要用于排序 |
TreeSet和TreeMap的联系和区别
与HashSet完全类似,TreeSet里面绝大部分方法都市直接调用TreeMap方法来实现的。
相同点:
- TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之间共享,不过可以使用方法Collections.synchroinzedMap()来实现同步。
- 运行速度都要比Hash集合慢,他们内部对元素的操作时间复杂度为O(logN),而HashMap/HashSet则为O(1)。
- TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是排好序的。
不同点:
最主要的区别就是TreeSet和TreeMap分别实现Set和Map接口
- TreeSet只存储一个对象,而TreeMap存储两个对象Key和Value(仅仅key对象有序)
- TreeSet中不能有重复对象,而TreeMap中value可以存在重复对象。
- TreeMap的底层采用红黑树的实现,完成数据有序的插入,排序。
什么时候用Set什么时候用Map呢?
Set和Map的使用场景
如果希望保证插入元素的唯一性,不希望出现重复值,那么可以选择一个 Set 的实现类,比如 HashSet、LinkedHashSet 或者 TreeSet。所有 Set 的实现类都遵循了统一约束比如唯一性,而且还提供了额外的特性比如 TreeSet 还是一个 SortedSet,所有存储于 TreeSet 中的元素可以使用 Java 里的 Comparator 或者 Comparable 进行排序。LinkedHashSet 也按照元素的插入顺序对它们进行存储。
如果是希望以键值的形式进行数据存储,那么用Map。根据需要选择Hashtable、HashMap或TreeMap。
HashSet与HashMap的区别
HashMap | HashSet |
---|---|
实现了Map接口 | 实现Set接口 |
存储键值对 | 仅存储对象 |
调用put()向map中添加元素 | 调用add()方法向Set中添加元素 |
HashMap使用键(Key)计算Hashcode | HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false |
HashMap相对于HashSet较快,因为它是使用唯一的键获取对象 | HashSet较HashMap来说比较慢 |