ArrayList 和 LinkedList对比-Java

ArrayListLinkedList 都是 Java 集合框架中的重要类,用来存储对象,它们实现了 List 接口,但在实现方式、性能和适用场景上有显著的差异。

1. 底层实现

  • ArrayList
    • 基于动态数组实现。
    • 当元素数量超过数组容量时,ArrayList 会重新分配更大的数组并复制原有数据,通常是原数组大小的 1.5 倍。
    • 查找元素的时间复杂度是 O(1),即随机访问非常快。
  • LinkedList
    • 基于双向链表实现。
    • 每个元素都包含一个数据部分和指向前一个和下一个元素的引用。
    • 查找元素的时间复杂度是 O(n),因为可能需要遍历链表。

2. 操作性能比较

操作 ArrayListLinkedList
访问元素(get) O(1) O(n)
插入元素(add) O(1)(在末尾) O(1)(在末尾)
删除元素(remove) O(n) O(1)(如果已知位置)
插入/删除(中间) O(n) O(n)

3. 内存消耗

  • ArrayList:只需要存储数据本身,内存开销较小。
  • LinkedList:除了数据本身,还需要存储前后节点的引用(指针),因此内存开销较大。

4. 适用场景

  • ArrayList

    • 适合频繁读取操作(访问元素)。
    • 插入/删除操作(尤其是中间位置的插入/删除)较慢。
    • 适用于元素较少变化的场景,或者当你只需要按顺序访问数据时。
  • LinkedList

    • 适合频繁插入/删除操作,尤其是在列表的开头或中间。
    • 不适合随机访问数据,因为访问某个元素需要遍历链表。
    • 适用于元素频繁变化的场景。

5. 具体代码示例

例子 1:ArrayList 使用示例

import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        // 创建一个 ArrayList
        ArrayList<String> arrayList = new ArrayList<>();
        
        // 添加元素
        arrayList.add("Apple");
        arrayList.add("Banana");
        arrayList.add("Cherry");

        // 访问元素
        System.out.println("First Element: " + arrayList.get(0));  // O(1)

        // 删除元素
        arrayList.remove("Banana");  // O(n)
        
        // 输出 ArrayList
        System.out.println("ArrayList: " + arrayList);  // [Apple, Cherry]
    }
}

例子 2:LinkedList 使用示例

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        // 创建一个 LinkedList
        LinkedList<String> linkedList = new LinkedList<>();
        
        // 添加元素
        linkedList.add("Apple");
        linkedList.add("Banana");
        linkedList.add("Cherry");

        // 访问元素(需要遍历)
        System.out.println("First Element: " + linkedList.get(0));  // O(n)

        // 删除元素
        linkedList.remove("Banana");  // O(n)
        
        // 输出 LinkedList
        System.out.println("LinkedList: " + linkedList);  // [Apple, Cherry]
    }
}

例子 3:ArrayListLinkedList 性能对比

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ListPerformanceTest {
    public static void main(String[] args) {
        // 测试元素个数
        int size = 100000;

        // 测试 ArrayList 性能
        List<Integer> arrayList = new ArrayList<>();
        long startTime = System.nanoTime();
        for (int i = 0; i < size; i++) {
            arrayList.add(i);
        }
        long endTime = System.nanoTime();
        System.out.println("ArrayList Insert Time: " + (endTime - startTime) + "ns");

        // 测试 LinkedList 性能
        List<Integer> linkedList = new LinkedList<>();
        startTime = System.nanoTime();
        for (int i = 0; i < size; i++) {
            linkedList.add(i);
        }
        endTime = System.nanoTime();
        System.out.println("LinkedList Insert Time: " + (endTime - startTime) + "ns");
    }
}

输出(可能的结果)

ArrayList Insert Time: 1357875ns
LinkedList Insert Time: 2877456ns
  • ArrayList:适合随机访问(O(1))和顺序插入。它的内存开销较小,但在中间插入和删除元素时比较慢。
  • LinkedList:适合频繁的插入和删除操作,尤其是在开头或中间的插入/删除(O(1))。但由于需要遍历链表,随机访问性能较差(O(n))。

选择使用 ArrayList 还是 LinkedList,取决于应用场景的具体需求,尤其是对性能要求的不同。如果对插入/删除操作的性能要求更高,可以优先考虑 LinkedList;如果需要快速随机访问数据,则可以选择 ArrayList

#java面经#
Java碎碎念 文章被收录于专栏

来一杯咖啡,聊聊Java的碎碎念呀

全部评论

相关推荐

10-28 17:30
已编辑
华东交通大学 Java
iori2333:这太正常了 我字节面了四五轮 没有一次是在官网投递 都是hr主动捞
秋招笔试记录
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务