面试系列Java基础:List、Map、Set有何区别?

集合类是Java开发最常用的工具,也是面试中经常被问到的问题。  Java提供了一个高性能的集合框架,主要包括两类容器:一类是集合,存放元素的集合;另一个是映射,用于存储键/值对映射。

面试系列Java基础:List、Map、Set有何区别?_第1张图片

Collection可以分为三种接口类型:Set、List和Queue,Map不属于Collection。  Map接口是一个独立的数据结构,它也依赖于Collection接口,而Collection接口又依赖于Iterator接口,这样所有的集合类型都可以统一地从中取出元素。

List接口类型

List 类型的集合是有序集合,其特点是精确控制每个元素的位置,用户可以通过整数索引访问元素。  List 集合中的元素可以重复。  List集合常用的子类包括:ArrayList、LinkedList、Vector。  

  • ArrayList 继承自 AbstractList 并实现了 List 接口。底层基于数组,实现容量的动态变化。  ArrayList 按照相加的顺序排列。如果要根据元素的值对ArrayList 进行排序,可以调用Collection.sort() 方法并提供Comparator。  

  • LinkedList 基于双向链表。每个节点维护用于遍历链表的 prev 和 next 指针。同时,链表还维护了first和last指针,分别指向第一个元素和最后一个元素。  LinkedList 不是线程安全的。  

  • Vector 与 ArrayList 非常相似,也是继承自 AbstractList。两者在并发安全性方面存在差异。  Vector 是线程安全的,而 ArrayList 是线程不安全的。当 Vector 创建一个 Iterator 并使用它时,另一个线程会改变 Vector 的状态,比如添加或删除一些元素,然后调用 Iterator 方法会抛出异常。

Set接口类型

Set 类型集合存储无序和非重复的数据,而 List 存储有序和可重复的元素。是否允许重复项是Set和List最大的区别。Set检索效率低,删除和插入效率高,因为插入和删除不会引起Set中元素位置的变化。列表正好相反。查找元素效率高,但插入删除效率低,因为插入删除会导致元素位置发生变化。  

Set类型的常用实现类:HashSet和TreeSet。两者都不是线程安全的。  

  • HashSet 以哈希表的形式存储元素,快速插入和删除。  HashSet 不能保证元素的顺序,顺序可能会发生变化。  

  • TreeSet 底层基于二叉树,可以保证集合元素处于排序状态。  TreeSet 支持两种排序方式,自然排序和自定义排序,其中自然排序是默认的排序方式。  TreeSet 的自然排序是按照集合元素的大小升序排列的。如果要自定义排序,则应使用 Comparator 接口。

Map接口类型

与 List 和 Set 不同,Map 类型不是 Collection 接口的继承。那么什么是 Map 类型呢?  

     在数组中,内容由数组下标索引。在 Map 中,内容(也是一个对象)由对象索引。用于索引的对象称为键,其对应的内容对象称为值。这就是我们通常所说的键值对。Map 的 entrySet() 方法返回实现 Map.Entry 接口的对象集合。集合中的每个对象都是 Map 中的一个键值对。  

Map常用的实现类有HashMap和TreeMap,类似于HashSet和TreeSet。  

  • HashMap 基于哈希表实现。它适用于在 Map 中插入、删除和定位元素。  

  • TreeMap 基于红黑树实现。适用于以自然顺序或自定义顺序遍历键。  

 HashMap 通常比 TreeMap 快。由于树和哈希表的数据结构,一般场合建议多用HashMap,需要排序时才用TreeMap。  HashMap 和 TreeMap 都不是线程安全的。  AbstractMap 的子类 HashTable 是线程安全的。但是,不建议使用此类。建议在多线程环境下使用JUC包中的ConcurrentHashMap类。

总结

最后我们用下表将List、Set和Map的常见集合类型做一个总结

面试系列Java基础:List、Map、Set有何区别?_第2张图片

基于以上不同集合类型的特点,我们应该根据实际情况选择合适的数据类型。以上类型主要用于栈(thread-specific)。对于需要线程安全的场合,建议选择JUC包中支持并发的集合类型。

你可能感兴趣的:(技术面试,java,后端,面试)