您现在的位置是:首页 > 技术人生 > 后端技术后端技术
JDK源码解读之ArrayList初始化、扩容机制、常用方法__java面试宝典
高晓波2020-06-20【后端技术】人已围观
简介此ArrayList源码的JDK版本:1.8。
一、首先,我们关注一下ArrayList有哪些属性:
此ArrayList源码的JDK版本:1.8。
2、一个空数组EMPTY_ELEMENTDATA;
3、又一个空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
4、一个未初始化的数组elementData;
5、容量size;
1、ArrayList指定长度构造方法,当指定长度大于0时,新建一个Object空数组,长度为指定长度,赋值给elementData;为0时将EMPTY_ELEMENTDATA赋值给elementData;小于0则报错;
2、无参构造方法:将空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给elementData。注意:无参构造上的注释说,构造了一个容量为10的空数组,其实并没有!
3、传入一个Collection对象初始化:将Collection对象转换为数组并赋值给elementData,将Collection长度赋值给size,判断c.toArray()是否为Object数组,不是则要转换为Object数组。为了集合能存储不能数据类型数据;
1、空ArrayList首次add时,会将数组长度初始化为默认长度10;
2、如果执行add方法时,ArrayList中的elementData长度装不下时,会将elementData扩容至原来长度的1.5倍;
2)public void add(int index, E element)方法
ArrayList指定index插入元素时,将index后(包括index的元素)的元素往后挪一位,再插入元素。
3)public E remove(int index)方法
ArrayList的remove方法:将index后元素前移,再将最后一个有值元素置null;
4)public boolean remove(Object o)方法
通过循环找元素的下标,然后remove
5)public void clear()方法
将elementData所有元素置null,将size置为0;
JAVA面试宝典目录: 《JAVA经典面试题整理》
一、首先,我们关注一下ArrayList有哪些属性:
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
1、默认容量DEFAULT_CAPACITY 10;
2、一个空数组EMPTY_ELEMENTDATA;
3、又一个空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
4、一个未初始化的数组elementData;
5、容量size;
二、再看看ArrayList构造方法
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);
}
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
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;
}
}
1、ArrayList指定长度构造方法,当指定长度大于0时,新建一个Object空数组,长度为指定长度,赋值给elementData;为0时将EMPTY_ELEMENTDATA赋值给elementData;小于0则报错;
2、无参构造方法:将空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给elementData。注意:无参构造上的注释说,构造了一个容量为10的空数组,其实并没有!
3、传入一个Collection对象初始化:将Collection对象转换为数组并赋值给elementData,将Collection长度赋值给size,判断c.toArray()是否为Object数组,不是则要转换为Object数组。为了集合能存储不能数据类型数据;
三、ArrayList常用方法
1)public boolean add(E e)方法
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
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);
}
1、空ArrayList首次add时,会将数组长度初始化为默认长度10;
2、如果执行add方法时,ArrayList中的elementData长度装不下时,会将elementData扩容至原来长度的1.5倍;
2)public void add(int index, E element)方法
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
ArrayList指定index插入元素时,将index后(包括index的元素)的元素往后挪一位,再插入元素。
3)public E remove(int index)方法
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
ArrayList的remove方法:将index后元素前移,再将最后一个有值元素置null;
4)public boolean remove(Object o)方法
/**
* Removes the first occurrence of the specified element from this list,
* if it is present. If the list does not contain the element, it is
* unchanged. More formally, removes the element with the lowest index
* <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
* (if such an element exists). Returns <tt>true</tt> if this list
* contained the specified element (or equivalently, if this list
* changed as a result of the call).
*
* @param o element to be removed from this list, if present
* @return <tt>true</tt> if this list contained the specified element
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
通过循环找元素的下标,然后remove
5)public void clear()方法
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
*/
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
将elementData所有元素置null,将size置为0;
JAVA面试宝典目录: 《JAVA经典面试题整理》
Tags:java面试题
很赞哦! ()
相关文章
随机图文
-
通过Redis限制API调用次数
最近在做微信公众号返利机器人,通过曲线救国的方式拿到的淘宝客工具商权限(用别人的App Key),在服务器搭建了透传程序。 使用过程中发现一个问题:阿里妈妈对淘宝API的调用频率有限制,报错信息反馈是40次/秒。 -
【转】GPT 应用开发和思考
在过去几个月的时间中,我们似乎正处于人工智能的革命中。除了大多数人了解的 OpenAI ChatGPT 之外,许多非常新颖、有趣、实用的 AI 应用也是层出不穷,并且在使用这些应用时时,笔者也确确实实的感受到了生产力的提高。 -
maven安装jar到本地仓库
JAVA做淘宝客程序开发的时候,我用的是maven管理依赖jar包。 如何将阿里妈妈下载的jar包以及source jar安装到maven本地仓库呢? -
Springboot集成quartz定时任务可视化配置
使用quartz定时任务已经有一段时间了,今天记录一下Springboot 2.x集成Quartz。