List 列表的常用实现类的特点及比较

在这里插入图片描述
List 本身的特点是有序,可重复,支持索引。它有三种常用的实现类

ArrayList

  • 在这其中,ArrayList 是最常用的实现类,其底层维护了一个 Object 类型的数组以存放数据
transient Object[] elementData; // 底层数组定义代码
  • 使用无参构造器创建 ArrayList 时,elementData 初始容量为 0 ,第一次添加元素时扩容为 10 ,如需再次扩容,则扩容为当前容量的 1.5 倍
  • 如果使用的是指定大小的构造器,elementData 初始容量为指定大小,如需扩容,则扩容为当前容量的 1.5 倍
  • 扩容时底层使用的是 Arrays.copyof() ,很耗费时间。所以我们一般会给一个合适的初始容量,过大浪费空间,过小经常扩容浪费时间

Vector

  • 相较于 ArrayList 最大的特点是线程安全,其余基本等同
  • 无参构造 Vector 时,elementData 初始容量直接为 10 ;有参构造就是指定初始容量。如需扩容,则扩容为当前容量的 2 倍

LinkedList

  • 底层维护了内部类 Node 作为其节点,Node 中维护了 prev 指向前一个 Node 对象、next 指向后一个,item 维护数据。以此构成了类似于双向链表的数据结构,在增删时只需要维护 Node 指向即可

ArrayList 与 LinkedList 的比较

这里就比较重要了,我们在学习数据结构时常常被问到数组和链表的优势——数组改查快、链表增删快

但上述结论在 ArrayList 和 LinkedList 的比较中并没有体现出来。无论是增删还是改查,永远都是 ArrayList 的效率高于 LinkedList ,而 ArrayList 和 LinkedList 的后部增删效率都是高于前部的

这就比较奇怪,ArrayList 的后部效率高于前部可以理解,后部元素增删时需要移位的元素较少,但为何 LinkedList 的后部效率高于前部我就不得而知了,我也不愿深究,因为我在工作中是不会使用 LinkedList 的

下面为我的测试代码,供各位参考

public class Main {
    public static void main(String[] args) {
        // List 元素个数:1千万
        int size = 10000000;
        // ArrayList 增删速度
        System.out.println("arrayList---------------------");
        listSpeed(size, new ArrayList());
        // LinkedList 增删速度
        System.out.println("linkedList--------------------");
        listSpeed(size, new LinkedList());
    }

    public static void listSpeed(int size, List list) {
        // 构建 List
        for (int i = 0; i < size; i++) {
            list.add(i);
        }
        // 开始时间
        long start = System.currentTimeMillis();
        // 测试内容1:对 List 中部之前进行 1000 次的随机增删
        for (int i = 0; i < 1000; i++) {
            int random = RandomUtil.randomInt(5000000);
            list.remove(random);
            list.add(random, random);
        }
        // 结束时间
        long end1 = System.currentTimeMillis();
        // 测试结果:单位s
        System.out.println((end1 - start) / 1000.0); // 5.342    36.712

        // 测试内容2:对 List 中部之后进行 1000 次的随机增删
        for (int i = 0; i < 1000; i++) {
            int random = RandomUtil.randomInt(5000000, 10000000);
            list.remove(random);
            list.add(random, random);
        }
        // 结束时间
        long end2 = System.currentTimeMillis();
        // 测试结果:单位s
        System.out.println((end2 - end1) / 1000.0); // 0.863    14.396
    }
}
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值