ArrayList于LinkedList的区别

List

按添加顺序排列的集合,予许元素重复,且可以为 null。

主要说下List下的两大常用子类ArrayListLinkedList

ArrayList

底层基于一个数组实现,数组长度可动态扩容。数组默认长度 10。‘

LinkedList

底层基于链表实现,不需要扩容。

ArrayListLinkedList 有什么区别呢?

增删查改的区别就不说了。分析下内存占用方面。

首先 先了解下一个对象实例占用多少内存。以64位压缩后的情况
对象占用内存都是8的倍数。

  • 对象头 12字节。
  • 基本数据类型成员变量占用字节,例如 byte(1字节) int(4字节)。
  • 数组,对象,都是属于引用类型,占4字节。
  • 对齐填充字节。

以简单点来说:就以这两大List集合都有的成员属性(size,元素) 来讲解内存占用情况。
都是以泛型Integer为例。

ArrayList 内存占用

占用内存 对象头(12字节) + elementData(4字节) + size(4字节) + modCount (4字节) = 24字节,刚刚好是8的倍数。这仅仅是一个ArrayList实例的占用内存,存储的元素并未计算。

public class ArrayList {
        /**
         * 数组引用  占用 4字节
         */
        transient Object[] elementData;

        /**
         * int类型  占用 4字节
         */
        private int size;  
        protected transient int modCount = 0;  // 4字节
    } 

一个Integer的占用内存是:对象头(12字节) + value(4字节) = 16字节。

public class Integer {
        // 4 字节
        private final int value;
    }

由于泛型是Integer,所以 elementData = new Integer[10]。10是默认值
那么占用的内存是 10 * 16 = 160字节。

由此可计算出 一个泛型IntegerArrayList10个容量的实例占用内存是 24字节 + 160字节 = 184字节。

LinkedList 内存占用

占用内存 对象头(12字节) + size(4字节) + first(4字节) + last(4字节) + modCount (4字节) = 28字节。由于28不是8的倍数 对齐填充4字节 = 32字节。
这仅仅是一个LinkedList实例的占用内存,存储的元素并未计算。

public class LinkedList {
        // 4 字节
        transient int size = 0;
        // 4 字节
        transient Node<E> first;
        // 4 字节
        transient Node<E> last;
        // 4 字节
        protected transient int modCount = 0;
    }

一个Node实例占用内存:对象头(12字节) + item(4字节) + next(4字节) + prev(4字节) = 24字节。

private static class Node<Integer> {
        // 4 字节
        E item;
        // 4 字节
        Node<E> next;
        // 4字节
        Node<E> prev;
    }

因为LinkedList每添加一个元素,就需要创建1个Node实例,所以一个泛型Integer元素占用 24字节 + 16字节 = 40字节。10个元素就是 10 * 40 = 400字节

由此可计算出 一个泛型IntegerLinkedList10个元素的实例占用内存是 24字节 + 400字节 = 424字节。


得出结论:以下是最少占用字节数,因为没有考虑其他成员属性。

  • ArrayList 泛型为 Integer,10个元素的内容占用为 184字节。
  • LinkedList泛型为 Integer,10个元素的内容占用为 424字节。

为什么深究于内存占用?

  • GC是在堆内存快不足的时候工作,GC工作的时候暂停所有用户线程。
  • 所以在编码过程中,应当减少内存的销耗,也就减少了GC。
  • 虽然占用内存不多,但苍蝇再小也是肉哇。

既然 ArrayList 的内存占用比 LinkedList内存少,那开发的时候就用ArrayList 咯? 这是错误的,不然也不会开发 LinkedList了,那这两个List集合什么场景下用?

ArrayList 应用场景

  • 在已知容量大小的情况下,例如JDBC查询数据。
  • 仅做查询。
  • 没有 add操作,仅有少量的 remove 操作。(这不会触发扩容,数组对象也就不会更换)
  • 可能存在 add 操作,或仅有一丢丢的 add 操作。

LinkedList 应用场景

  • 针对于不知道容量大小,例如缓存临时数据。
  • 数据操作频繁, add,remove。

在编码中,我们应该要保持活性,有时候可以选择的是时间换空间,也可以是空间换时间。
但是我们要时刻注意着写出来的代码是否占用了过多内存,且是否会导致GC。


纯属个人理解,如有不同意见,请勿采纳。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Me_Liu_Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值