第8讲 | 对比Vector、ArrayList、LinkedList有何区别?

典型回答

这三者都是实现集合框架中的 List,也就是所谓的有序集合,提供相似的操作,因为具体的设计区别,在行为、性能、线程安全等方面,表现又有很大不同。

Vector: 线程安全得动态数组,内部是使用对象数组来保存数据,可以根据需要自动的增加容量,当数组已满时,会创建新的数组,并拷贝原有数组数据。

ArrayList: 应用更加广泛的动态数组实现,线程不安全,性能好,Vector 在扩容时会提高 1 倍,而 ArrayList则是50%。

LinkedList: 双向链表,线程不安全。

适用场景

  • Vector 和 ArrayList 作为动态数组,其内部元素顺序存储,所以非常适合随机访问的场合。插入和删除元素(除了尾部)需要移动后续所有元素,性能较差。

  • LinkedList 进行节点插入、删除却要高效得多,但随即访问性能较差。

在应用开发中,如果事先可以估计到,应用操作是偏向于插入、删除,还是随机访问较多,就可以针对性的进行选择。

狭义的集合框架(不包括Map)

image.png

  • TreeMap/TreeSet 支持自然顺序/自定义顺序,但是添加、删除、包含等操作要相对低效(log(n) 时间)

  • HashMap/HashSet 利用哈希算法,可以提供常数时间的添加、删除、包含等操作,但是它不保证有序。

  • LinkedHashMap/LinkedHashSet,内部构建了一个记录插入顺序的双向链表,因此提供了按照插入顺序遍历的能力,也保证了常数时间的变更操作,这些操作性能略低于HashMap,因为维护链表的开销。

  • 以上集合都符合迭代时 fail-fast 行为,当发生意外的并发修改时,尽早抛出 ConcurrentModificationException 异常,以避免不可预计的行为。

  • 在遍历元素时,HashMap 性能受自身容量影响,所以初始化,除非有必要,不然不要将其背后的 HashMap 容量设置过大。LinkedHashSet,由于其内部链表提供的方便,遍历性能只和元素多少有关系。

对于线程不安全的集合,可以利用Collections 工具类中,提供了一系列的 synchronized方法,例如

List list = Collections.synchronizedList(new ArrayList());

实现原理是所有访问方法通过synchronizd 添加基本的同步支持,简单粗暴。

Arrays.sort()的排序算法

  • 对于原始数据类型,目前使用的是所谓双轴快速排序(Dual-Pivot QuickSort),是一种改进的快速排序算法。
  • 对于对象数据类型,目前则是使用TimSort,思想上也是一种归并和二分插入排序(binarySort)结合的优化排序算法。

Java9 集合类提供了一系列静态方法,例如,List.of()、Set.of(),大大简化了构建小的容器实例的代码量。根据业界实践经验,我们发现相当一部分集合实例都是容量非常有限的,而且在生命周期中并不会进行改变。

// 一句代码创建list,且是immutable
List<String> simpleList = List.of("Hello","world");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。