面试题学习: LinkedList与ArrayList

目的

面试准备, 方便自己后续面试复习方便, 可能用不大, 这里做一个简单的个人学习记录.

资源

B站的一个讲高频面试题的一个学习视频

核心知识点

4个维度比较:

  1. 结构
  2. 随机访问速度
  3. 插入与删除
  4. CPU缓存, 局部性原理
    结论:
  • ArrayList
    ① 基于数组, 是联系的内存空间
    ②随机访问快(根据下标访问)
    ③尾部插入/删除性能可以, 其他部分插入/删除会涉及移动元素, 性能会降低
    ④可以利用CPU缓存, 局部性原理
  • LinkedList
    ① 基于双向链表, 无需连续的内存
    ②随机访问慢(需要沿着链表去遍历)
    ③头尾插入删除性能高(中间插入可能还不如ArrayList, 主要时间浪费在找元素)
    ④占用内存多

自验证源码

测试随机访问

    private static void randomAccess(List<Integer> list1, LinkedList<Integer> list2, int mid) {
    
    
        StopWatch sw = new StopWatch("测试随机访问");
        sw.start("测试随机访问: ArrayList");
        list1.get(mid);
        sw.stop();
        sw.start("测试随机访问: LinkedList");
        list2.get(mid);
        sw.stop();
        System.out.println(sw.prettyPrint());
    }

结论: 随便访问 ArrayList 优秀, 直接通过下标获取, 而 LinkedList 需要遍历元素

StopWatch '测试随机访问': running time = 13501 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
000004000  030%  测试随机访问: ArrayList
000009501  070%  测试随机访问: LinkedList

测试头部插入

    private static void addFirst(List<Integer> list1, LinkedList<Integer> list2) {
    
    
        StopWatch sw = new StopWatch("测试头部插入");
        sw.start("ArrayList: ");
        list1.add(0, 100);
        sw.stop();
        sw.start("LinkedList: ");
        list2.addFirst(100);
        sw.stop();
        System.out.println(sw.prettyPrint());
    }

结论: 头部插入 LinkedList 性能好, 不用去移动元素.

StopWatch '测试头部插入': running time = 15301 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
000011301  074%  ArrayList: 
000004000  026%  LinkedList: 

测试中间插入

    private static void addMiddle(List<Integer> list1, LinkedList<Integer> list2, int mid) {
    
    
        StopWatch sw = new StopWatch("测试中间插入");
        sw.start("ArrayList: ");
        list1.add(mid, 100);
        sw.stop();
        sw.start("LinkedList: ");
        list2.add(mid, 100);
        sw.stop();
        System.out.println(sw.prettyPrint());
    }

结论: 一般 ArrayList 好一点, LinkedList 找元素会花费很多时间.

StopWatch '测试中间插入': running time = 10500 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
000001299  012%  ArrayList: 
000009201  088%  LinkedList: 

测试尾部插入

    private static void addLast(List<Integer> list1, LinkedList<Integer> list2) {
    
    
        StopWatch sw = new StopWatch("测试尾部插入");
        sw.start("ArrayList: ");
        list1.add(100);
        sw.stop();
        sw.start("LinkedList: ");
        list2.add(100);
        sw.stop();
        System.out.println(sw.prettyPrint());
    }

结论: 差不多.

StopWatch '测试尾部插入': running time = 3900 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
000002301  059%  ArrayList: 
000001599  041%  LinkedList: 

局部性原理, 空间占用测试

结论: LinkedList 更占空间.

猜你喜欢

转载自blog.csdn.net/xiaozhengN/article/details/127190143
今日推荐