编程语言   发布时间:2022-06-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了java数据结构之ArrayList大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

ArrayList是java语言中使用最广泛的一种集合,它的底层是基于数据实现的。今天我就来带大家彻底搞懂ArrayList的一些技术细节。 我们都知道,ArrayList底层是基于数组来实现。数组这种数据结构的最大优点,就是支持随机查询,因为在内存中,数组是一块连续的存储空间,只要知道数组的起始地址,一级数组中某个元素的下标,我们很容易就能计算出这个元素的地址,从而查询出它的结果。但是ArrayList和原生的数组最大的不同就是,原生的数组一旦定义了,它的容量不能改变,但是ArrayList,我们知道,可以一直向其中添加元素。 这就要要探讨ArrayList底层的源码。 ArrayList类中有如下几个重要的参数: 1.默认的初始容量 private static final int DEFAULT_CAPACITY = 10; 2.空数组用于初始化一个长度为0的数组 private static final Object[] EMPTY_ELEMENTDATA = {}; 3.空数组,用于判断何时使用默认的初始容量 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 具体这个数组的功能我们接下来介绍。 4.用于存放具体元素的数组 transient Object[] elementData; 5.ArrayList中实际存放的元素个数,注意不是ArrayList的容量 privatE int size;

ArrayList的构造函数 1.默认的构造函数 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } 如果我们初始化一个ArrayList的时候不指定它的容量,默认第一次将它初始化为一个空数组。

2.带参数的构造函数 public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentexception("Illegal Capacity: "+ initialCapacity); } } 如果我们初始化Arraylist的时候,指定它的容量,则会创建一个指定容量的数组。

3.用于将其他集合转换成数组的构造函数 public ArrayList(Collection<? extends E> C) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } } 这种方法常用于将其他集合类转换成数组,例如Stack,LinkedList等等,这里不做赘述。

下面我将分两种情况讲述ArrayList的初始化,以及向其中添加元素的过程。 第一种情况,初始化的时候不指定容量, public Boolean add(E E) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } 首先 ensureCapacityInternal(size + 1); 用于判断向数组中添加元素,是否超过数组的容量。 private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); }

    ensureExplicitCapacity(minCapacity);

} 当我们第一次向数组中添加元素的时候 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 条件满足,于是这时会将 minCapacity会取到默认的初始容量10,然后进入到ensureExplicitCapacity(minCapacity) 方法判断是否此时超过数组的容量 private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } 此时elementData数组长度为0,所以会进入grow(minCapacity) 方法进行扩容; private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }

第一次的时候oldCapacity = 0,所以第一次会将数组容量扩充到默认的10,后续会在之前的基础上扩容50%。 oldCapacity >> 1 表示右移一位,相当于除以2。

这是不指定参数的ArrayList的初始化的流程。

如果初始化的时候指定数组的大小,则此时没有第一次将数组从0扩容到初始容量的过程。因为第一次初始化的时候 this.elementData = new Object[initialCapacity]; 已经将elementData数组初始化为一个。

大佬总结

以上是大佬教程为你收集整理的java数据结构之ArrayList全部内容,希望文章能够帮你解决java数据结构之ArrayList所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。