• java(ArrayList、Vector、LinkedList底层结构和源码分析)


    ArrayList:

    (1)允许所有元素,包含null,可以加入多个null

    (2)ArrayList是由数组来实现数据存储的

    (3)ArrayList基本等同于Vector,除了ArrayList是线程不完全(执行效率高),在多线程情况下,不建议使用ArrayList

    源码分析

    1、ArrayList中维护了一个Object类型的数组elementData

    transient:该属性不能被序列化 

    2、当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍

    1. private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    2. public ArrayList() {
    3. this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    4. }
    5. //第一步,判断是否添加成功
    6. public boolean add(E e) {
    7. modCount++;
    8. add(e, elementData, size);
    9. return true;
    10. }
    11. //第二步,判断是否需要扩容
    12. private void add(E e, Object[] elementData, int s) {
    13. if (s == elementData.length)
    14. elementData = grow();
    15. elementData[s] = e;
    16. size = s + 1;
    17. }
    18. //第三步,进入扩容
    19. private Object[] grow() {
    20. return grow(size + 1);
    21. }
    22. //第四步
    23. private Object[] grow(int minCapacity) {
    24. return elementData = Arrays.copyOf(elementData,
    25. newCapacity(minCapacity));
    26. }
    27. //第五步,如果是第一次无参构造器扩容,则返回默认值10,之后返回容量值的1.5倍
    28. private int newCapacity(int minCapacity) {
    29. // overflow-conscious code
    30. int oldCapacity = elementData.length;
    31. int newCapacity = oldCapacity + (oldCapacity >> 1);
    32. if (newCapacity - minCapacity <= 0) {
    33. if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
    34. return Math.max(DEFAULT_CAPACITY, minCapacity);
    35. if (minCapacity < 0) // overflow
    36. throw new OutOfMemoryError();
    37. return minCapacity;
    38. }
    39. return (newCapacity - MAX_ARRAY_SIZE <= 0)
    40. ? newCapacity
    41. : hugeCapacity(minCapacity);
    42. }

    3、如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要再次扩容,则直接扩容elementData为1.5倍(扩容方式同无参构造器基本相同)

    1. public ArrayList(int initialCapacity) {
    2. if (initialCapacity > 0) {
    3. this.elementData = new Object[initialCapacity];
    4. } else if (initialCapacity == 0) {
    5. this.elementData = EMPTY_ELEMENTDATA;
    6. } else {
    7. throw new IllegalArgumentException("Illegal Capacity: "+
    8. initialCapacity);
    9. }
    10. }

    Vector:

    1、Vector类的定义:

    public class Vector<E>
        extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    

    2、Vector底层也是一个对象数组

    protected Object[] elementData;

    3、Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized

    4、在开发中,需要线程同步安全时,考虑使用Vector

    1. //调用无参构造器的本质还是调用其有参构造器
    2. public Vector(int initialCapacity, int capacityIncrement) {
    3. super();
    4. if (initialCapacity < 0)
    5. throw new IllegalArgumentException("Illegal Capacity: "+
    6. initialCapacity);
    7. this.elementData = new Object[initialCapacity];
    8. this.capacityIncrement = capacityIncrement;
    9. }

    5、扩容方式与ArrayList方式基本相同,但Vector默认为二倍的扩容或指定扩容大小

    1. private int newCapacity(int minCapacity) {
    2. // overflow-conscious code
    3. int oldCapacity = elementData.length;
    4. //capacityIncrement可以指定扩容大小,默认为0
    5. int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
    6. capacityIncrement : oldCapacity);
    7. if (newCapacity - minCapacity <= 0) {
    8. if (minCapacity < 0) // overflow
    9. throw new OutOfMemoryError();
    10. return minCapacity;
    11. }
    12. return (newCapacity - MAX_ARRAY_SIZE <= 0)
    13. ? newCapacity
    14. : hugeCapacity(minCapacity);
    15. }

    LinkedList:

    1、LinkedList底层实现了双向链表和双端队列特点

    2、可以添加任意元素(可重复),包括null

    3、线程不安全,没有实现同步

    底层操作机制:

    1.LinkedList底层维护了一个双向链表

    2.LinkedList中维护了两个属性first和last分别指向首节点和尾节点

    3.每个结点(Node对象)里面又维护了prev、next、item三个属性,其中通过prev指向前一个节点,通过next指向后一个节点,最终实现双向链表

    4、LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高

    1. //添加节点
    2. void linkLast(E e) {
    3. final Node<E> l = last;
    4. final Node<E> newNode = new Node<>(l, e, null);
    5. last = newNode;
    6. if (l == null)
    7. first = newNode;
    8. else
    9. l.next = newNode;
    10. size++;
    11. modCount++;
    12. }
    13. //删除指定位置节点
    14. E unlink(Node<E> x) {
    15. // assert x != null;
    16. final E element = x.item;
    17. final Node<E> next = x.next;
    18. final Node<E> prev = x.prev;
    19. if (prev == null) {
    20. first = next;
    21. } else {
    22. prev.next = next;
    23. x.prev = null;
    24. }
    25. if (next == null) {
    26. last = prev;
    27. } else {
    28. next.prev = prev;
    29. x.next = null;
    30. }
    31. x.item = null;
    32. size--;
    33. modCount++;
    34. return element;
    35. }

  • 相关阅读:
    [单片机框架][bsp层][N32G4FR][bsp_uart] UART配置和使用
    个人项目中用到的Flume 各组件,以及Put 事务和Take 事务介绍
    .NET 6学习笔记(4)——解决VS2022中Nullable警告
    pyqt生成.py文件和资源打包
    Profile注解
    2023黑龙江大学计算机考研信息汇总
    [JavaWeb基础(三)]HTTP请求消息与登录案例分析
    论文阅读《Large-Scale Direct SLAM with Stereo Cameras》
    【Kafka】Kafka指标报告器 MetricsReporter ClusterResourceListener
    pom报红
  • 原文地址:https://blog.csdn.net/weixin_63954483/article/details/125411801