前几天看到一篇文章,里面特意提到了,读取频繁使用ArrayList,增删频繁使用Linkedlist;并且在一个范例中,特意将ArrayList转化为LinkedList以提高末尾插入的效率。而事实上,问题并非如此简单。
ArrayList与LinkedList的异同是我面试较常问的问题。大部分人可能都知道前者基于数组而后者基于链表(能答出双向链表自然更好),并且前者适合读取、后者适合插入删除;偶有候选人能曰“It depends”并给出具体情况之分析时,往往能获得不错的第一印象。
抛开具体语言的实现不说,先从数据结构上看一下,两者时间、空间负责度上的区别:
查找自不必说,插入删除与具体的位置有关,如果在首部、中部执行增删,考虑到ArrayList需要复制指定位置之后的所有元素,因此具有O(N)的时间复杂度;而LinkedList则只需O(1)。
如果是尾部增加、删除的情况,ArrayList不需要移动任何元素,因此两者的理论时间复杂度都为
O(1)。考虑得更细一点,如果是尾部增加的情况,LinkedList需要重新向JVM申请内存空间,而ArrayList不需要,因其一开始就会申请较多的空间,并且可以通过初始化capacity来避免动态膨胀的开销;如果是尾部减少的情况,LinkedList或许会带来GC释放内存的开销,而ArrayList仅需简单的将length减一;并且考虑到今后的扩展性,无论是哪种情况,使用ArrayList要划算得多。
另外,特别提一下删除操作,我前面特意强调“抛开具体语言不说”,是因为虽然理论上LinkedList的随机增删的时间复杂度是O(1),但那是对于传入的是其内部某节点指针或者entry而言的,而事实上,在JAVA中由于不存在指针一说,并且对其数据结构的完美隐藏,大部分情况我们不会直接传入某个entry,而是基于以下两种情况的元素删除:
- 删除特定index的元素,对应LinkedList.remove(int)方法
- 删除特定值的元素,LinkedList.remove(Object)
事实上,对于上述情况,在删除前势必需要一个定位查找的工作,而众所周知,LinkedList在元素遍历上相当低效的,因此删除元素的时间复杂度应该是O(1) + O(N),也就是O(N)。当然java进行了优化,譬如说采用折半查找索引的方式
Entry<E> e = header;
if (index < (size >> 1)) {
//looking forward
for (int i = 0; i <= index; i++)
e = e.next;
} else {
//looking backward
for (int i = size; i > index; i–)
e = e.previous;
}
尽管如此,还是不敌ArrayList的O(1)。特别的,对于LinkedList.remove(int)方法来说,LinkedList定位慢而删除快,ArrayList定位快而删除慢,因此具体谁领风骚还真不好说,不仅与具体操作的位置有关,还与集合中元素的数量有关。
麻雀虽小五脏俱全,一个小小的LinkedList居然衍生出这么多的花样。以后对于LinkedList增删优于ArrayList一说,切不可一言以蔽之
- 大小: 31.7 KB
分享到:
相关推荐
Java语言在实际应用中充满了各种陷阱,这些陷阱可能在编程过程中导致意料之外的问题,对程序的稳定性和性能造成影响。对于求职者来说,熟悉这些陷阱并在面试中能够准确解答,是展示自身技能水平的重要方式。本文将...
Java程序员在面试过程中可能会遇到各种陷阱,这些陷阱可能源于对技术理解的深度、广度,或是面试技巧的不足。这份48页的PDF文档“Java程序员面试陷阱”旨在揭示这些问题,帮助求职者避免在关键面试时刻掉入这些误区...
- 面试陷阱:面试官可能会询问ArrayList和LinkedList的区别,或者HashMap的工作原理。 - 解析:Java集合框架包括List、Set、Map等接口及其实现类。ArrayList适合随机访问,LinkedList适合频繁插入和删除。HashMap...
7. **数组与集合**:数组是固定大小的,而集合如ArrayList和LinkedList具有动态增长能力。选择合适的数据结构很重要,同时,遍历集合时要注意迭代器的使用。 8. **字符串处理**:`String`是不可变的,`...
5. **集合框架**:深入理解ArrayList、LinkedList、HashSet、HashMap等集合类的内部实现,包括它们的时间复杂度和适用场景。知道ConcurrentHashMap在并发下的优势。 6. **反射机制**:理解反射的基本用法,如Class...
6. **集合框架**:深入理解ArrayList、LinkedList、HashMap、HashSet等集合类的内部实现和性能特性,面试官可能会通过比较这些数据结构的差异来考察你的基础知识。 7. **泛型**:泛型是Java中一种强大的类型安全...
- 知道ArrayList和LinkedList的区别,HashMap和ConcurrentHashMap的工作原理。 - 探讨泛型、迭代器、并发容器(如ConcurrentHashMap、CopyOnWriteArrayList)的使用。 7. **反射与注解**: - 理解反射的概念,...
这篇文章将探讨Java面试中的一些常见陷阱,帮助求职者更好地准备面试。 首先,面试官可能会问到关于Java基础的问题,这包括但不限于语言特性、数据类型、内存管理等。例如,他们可能会询问Java的垃圾回收机制,如何...
Java集合框架是另一个常考领域,包括ArrayList、LinkedList、HashMap、TreeMap等容器的特性与使用场景,以及如何进行高效的集合操作。面试中可能会要求实现特定的集合操作,比如查找、排序或优化内存占用。 JVM...
3.3.3 ArrayList和LinkedList的性能分析和适用场景 3.4 Iterator迭代器 迭代时删除指定元素 3.5 小结 第4课 Java的内存回收 4.1 Java引用的种类 4.1.1 对象在内存中状态 4.1.2 强引用 4.1.3 软引用 4.1.4 ...
例如,了解HashMap的扩容机制、LinkedList的节点操作、ArrayList的动态数组管理等,能够帮助开发者在设计和实现自己的数据结构时避免常见陷阱。 6. **工具类**:Collections和Arrays类提供了很多实用的静态方法,如...
- item4可能涉及Java集合框架中的第4个主题,可能是关于ArrayList和LinkedList的区别。 - item13可能涵盖了异常处理的某个关键点,如何时使用checked异常和unchecked异常。 - item29可能讲解了多线程中的并发控制,...
"很容易弄错的Java面试题"通常涉及那些看似简单实则暗藏陷阱的问题,这些问题能够检验候选人在实际编程中的严谨性和对细节的把握。下面,我们将深入探讨一些经典的Java面试题及其背后的原理。 1. **对象的相等性**...
这些仅是JAVA编程中的一部分重要概念,实际的PDF文档可能会包含更多具体的应用示例、最佳实践和常见陷阱。对于JAVA开发者来说,深入理解和熟练运用这些知识点,不仅可以提高编程效率,也能提升代码质量,为公司的...
5. **集合框架**:Java集合框架是程序设计的基础,书中可能讨论`ArrayList`、`LinkedList`、`HashSet`、`HashMap`等容器的性能特征和使用场景,以及`Collections`和`Stream` API的使用技巧。 6. **泛型**:Java泛型...
7. **集合性能优化**:选择合适的集合类型以提升性能,以及避免常见的性能陷阱。 8. **实用工具类**:如Arrays、Collections和Guava库中的工具类,它们提供了丰富的静态方法来处理集合。 通过阅读"Java Generics ...
其次,书中深入探讨了Java集合框架,包括ArrayList、LinkedList、HashMap等数据结构。Java程序员经常需要处理各种数据结构的选择和操作,而这些谜题将揭示在特定场景下选择哪种数据结构更为合适,以及如何避免常见的...
- **ArrayList vs LinkedList**:对于频繁插入删除的场景,应该选择`LinkedList`;而如果主要是元素的读取操作,则`ArrayList`更合适。 - **空指针异常**:在向集合中添加元素之前,务必检查该元素是否为null,以...
6. **集合框架**:Java集合框架包括ArrayList、LinkedList、HashMap等,谜题可能涉及它们的性能特点、遍历方式以及使用注意事项。 7. **泛型**:Java的泛型为代码提供了类型安全性,但其类型擦除特性可能导致一些...