package com.pyi.MyLinkedList1;
import com.pyi.MyLinkedList.MyList;
import java.lang.annotation.Native;
import java.util.Arrays;
import java.util.Collection;
/**
* @ClassName ArrayList
* @date 2022/4/20
* version 1.0
*/
public class ArrayList extends MyList {
private static final int DEFAULT_CAPACITY = 10;//默认初始容量
private static final Object[] EMPTY_ELEMENTDATA = {};//用于空实例的共享空数组实例。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//用于默认大小的空实例的共享空数组实例。
transient Object[] elementData;//存储数组列表元素的数组缓冲区
private int size;//数组列表的当前大小
protected transient int modCount = 0;//迭代器
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//要分配的数组的最大大小
public static final int MAX_VALUE = 0x7fffffff;//常量2^31-1
/**
* 无参构造,构造一个初始容量为10的空列表
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 有参构造,构造一个具有初始容量的列表
*
* @param n-传入的数组的容量的大小
*/
public ArrayList(int n) {
if (n > 0) {//若传入的初始容量大于0,则数组的容量为传入的容量
this.elementData = new Object[n];
} else if (n == 0) {//若传入的初始容量等于0,则数组缓冲区的容量为EMPTY_ELEMENTDATA空数组的容量大小
this.elementData = EMPTY_ELEMENTDATA;
} else//若给定的初始容量小于0,则抛出IllegalArgumentException错误
{
throw new IllegalArgumentException("Illegal Capacity: " +
n);
}
}
/**
* 构造一个包含指定集合元素的列表,按照集合的迭代器返回元素的顺序排列。
*
* @param c-将其元素放置到此列表中的集合
*/
public ArrayList(Collection c) {
elementData = c.toArray();//返回包含此集合中所有元素的数组,并将它赋给数组elementDate
if ((size = elementData.length) != 0) {//若此列表不为空列表
if (elementData.getClass() != Object[].class) {//判断该数组是否为Object类,若不为Object类,则返回Object类的elementData数组的副本并更新elementData
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
} else {
elementData = EMPTY_ELEMENTDATA;//若此集合为空,则将elementData替换为空数组
}
}
/**
* 将数组的容量裁剪为当前数组的大小
*/
public void trimToSize() {//将数组的容量裁剪为当前数组的大小
modCount++;
if (size < elementData.length) {//如果数组的大小小于数组的容量
elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size);//若数组的当前的大小为0,则将空数组赋给elementData,否则将elementData的容量裁剪为当前数组元素的个数
}
}
/**
* 将指定的元素追加到列表的末尾。
*
* @param o-指定的添加的元素
* @return true
*/
@Override
public boolean add(Object o) {
ensureCapacityInternal(size + 1);//检查是否需要扩容
elementData[size++] = o;//将指定要添加的元素放在数组最后一个位置
return true;
}
/**
* 在此列表的指定位置插入指定元素。
*
* @param index-指定的位置
* @param o-指定插入的元素
*/
@Override
public void add(int index, Object o) {
rangeCheckForadd(index);//检查索引是否越界
ensureCapacityInternal(size + 1);//检查是否需要扩容
System.arraycopy(elementData, index, elementData, index + 1,
size - index);//将指定位置以及后面的元素往后移
elementData[index] = o;//将指定元素o赋值给数组的指定下标处
size++;//数组长度加一
}
/**
* 删除位于列表中指定位置的元素。
*
* @param index-指定的位置
* @return oldnum-原来位置的元素
*/
@Override
public Object remove(int index) {
rangeCheckForadd(index);//检查索引是否越界
Object oldnum = elementData[index];//获取指定位置的元素
int numMoved = size - index - 1;//获取指定位置后面的元素的个数
System.arraycopy(elementData, index + 1, elementData, index,
numMoved);//将指定位置后面的元素往左移覆盖指定位置的元素
elementData[--size] = null;//将原先数组的最后一个位置的值改为null
return oldnum;
}
/**
* 如果指定元素出现,则从列表中删除第一个出现的元素。
*
* @param o-指定的元素
* @return 若该列表含有指定元素则返回true, 否则返回false
*/
@Override
public boolean remove(Object o) {
for (int i = 0; i < size; i++) {//从下标为0开始检索
if (elementData[i] == o) {//若该位置的数组元素等于指定的元素
int numMoved = size - i - 1;
System.arraycopy(elementData, i + 1, elementData, i,
numMoved);//将该位置后面的元素往前移,覆盖该位置的元素
elementData[--size] = null;//将原先数组的最后一个值改为null
return true;
}
}
return false;
}
/**
* 跳过是否越界的查询快速删除某一位置的元素
* @param index -要删除的元素位置的索引
*/
private void fastRemove(int index){
modCount++;
int numMoved=size-index-1;//需要移动的元素的个数
if(numMoved>0){//如果需要移动的元素的个数大于0,则将原列表从指定位置的索引的后一个元素开始,向本列表从指定的位置处复制numMoved个数的元素
System.arraycopy(elementData,index+1,elementData,index,numMoved);
elementData[--size]=null;//将此列表原来的最后一个元素改为空
}
}
/**
* 返回该列表元素的个数
*
* @return size-该列表元素的个数
*/
@Override
public int size() {
return this.size;
}
/**
* 查找该列表是否含有指定元素
*
* @param o-指定的元素
* @return 如果列表中包含指定的元素,则返回true,否则返回false
*/
@Override
public boolean contains(Object o) {
for (int i = 0; i < size; i++) {
if (o == elementData[i]) {//若该位置的元素与指定元素相同,则返回true
return true;
}
}
return false;
}
/**
* 获取指定位置的元素
*
* @param index-指定的位置
* @return 指定位置的元素
*/
@Override
public Object get(int index) {
return elementData[index];
}
/**
* 将此列表中指定位置的元素替换为指定元素。
*
* @param index-指定的位置
* @param o-要替换成的元素
* @return o1-被替换的元素
*/
@Override
public Object set(int index, Object o) {
Object o1 = elementData[index];//获取原先数组的指定位置元素的值
elementData[index] = o;//将指定位置元素的值改为指定元素o
return o1;//返回原先指定位置元素的值
}
/**
* 从列表中删除所有元素。
*/
@Override
public void clear() {
for (int i = 0; i < size; i++) {
elementData[i] = null;//将所有元素赋值为null
}
size = 0;//将列表的长度改为0
}
/**
* 如果需要可扩容进而确保该列表至少可以容纳最小容量参数指定的元素数量。
*
* @param minCapacity -指定的最小元素容量
*/
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;//若该列表为空列表,则将minExpand的值赋为10,否则赋为0
if (minCapacity > minExpand) {//若指定的最小容量大于minExpand,则进行判断是否需要扩容
ensureExplicitCapacity(minCapacity);
}
}
/**
* 返回所分配列表的最大元素容纳量
*
* @param minCapacity -指定的最小元素容纳量
* @return 最大元素容纳量
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) {//如果指定的最小元素容纳量小于0,则抛出异常
throw new OutOfMemoryError();
} else {//若指定最小元素容纳量大于0,若指定的元素容纳量大于最大的数组分配的大小,则返回Integer.MAX_VALUE,否则返回最大的数组分配的大小
return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
}
/**
* 判断该列表是否一个元素都没有
* @return 若该列表一个元素都没有,则返回true,否则,返回false
*/
public boolean isEmpty() {
if (size == 0) {//若列表的大小为0,则此列表为空列表,一个元素都没有,返回true
return true;
}else{//否则,此列表不为空列表,返回false
return false;
}
}
/**
*返回列表中指定元素第一次出现的索引,如果列表中不含有该元素,则返回-1
* @param o -指定的元素
* @return 若该列表中含有指定的元素,则返回出现的指定的元素的第一个位置的索引。否则返回-1
*/
public int indexOf(Object o){
if(o==null) {//若该元素为空,则从下标从0开始索引,找到第一个出现的地址为空的元素
for (int i = 0; i < size; i++) {
if (elementData[i] == null) {
return i;
}
}
} else{//若元素不为空,则从0开始索引查找列表中是否含有指定的元素,若含有只当元素,则返回其出现的最小位置的索引
for(int i=0;i<size;i++){
if(o.equals(elementData[i])){
return i;
}
}
}
return -1;//若列表中不含有指定的元素,则返回-1
}
/**
* 返回指定元素出现的最后一个位置的索引,若列表中不含有该元素,则返回-1
* @param o -指定的元素
* @return 若列表中含有指定的元素,则返回该元素出现的最后一个位置的索引。否则,返回-1
*/
public int lastIndexOf(Object o){
if(o==null){//若该元素为空,则从下标从size-1开始索引,找到第一个出现的地址为空的元素
for(int i=size-1;i>=0;i--){
if(elementData[i]==null){
return i;
}
}
}else{
for(int i=size-1;i>=0;i--){//若元素不为空,则从size-1开始索引查找列表中是否含有指定的元素,若含有该指定元素,则返回指定元素出现的最大位置的索引
if(o.equals(elementData[i])){
return i;
}
}
}
return -1;//若列表中不含有指定的元素,则返回-1
}
/**将fromIndex到toIndex中间的元素删除,包含fromIndex,不包含toIndex,并将toIndex及其后面的元素往左移,填补前面的空缺
* @param fromIndex-要删除的开始位置的索引
* @param toIndex-要删除的结束位置的索引
*/
protected void removeRange(int fromIndex,int toIndex){
modCount++;
int numMoved=size-toIndex;//获取要移动的元素的个数
System.arraycopy(elementData,toIndex,elementData,fromIndex,numMoved);//将fromIndex(包含)与toIndex(不包含)之间的元素覆盖从而删除
int newSize=size-(toIndex-fromIndex);//此列表的现在的元素个数
for(int i=newSize;i<size;i++){//将此列表空缺位置的地址改为null
elementData[i]=null;
}
size=newSize;//更新列表的大小
}
/**
*返回包含此列表所有元素的数组
* @return 一个包含着按适当的顺序排列的这个列表的所有元素的数组
*/
public Object[] toArray(){
return Arrays.copyOf(elementData,size);
}
/**
* 返回只当位置的元素
* @param index -指定位置的索引
* @return 返回指定位置的元素
*/
Object elementData(int index){
return (Object)elementData[index];
}
/**
* 将指定的集合中的所有元素按一定的顺序添加到此列表的末尾
* @param c -要添加到此列表的元素的集合
* @return 若集合中的没有元素则返回false,否则返回true
*/
public boolean addAll(Collection c){
Object a[]=c.toArray();//获取集合c中的所有元素并赋给数组a
int newNum=a.length;//获取该数组的长度
ensureExplicitCapacity(size+newNum);//判断是否需要扩容
System.arraycopy(a,0,elementData,size,newNum);//将集合c中的元素添加到此列表的末尾
return newNum!=0;
}
/**
* 将指定的集合中的所有元素按一定的顺序添加到此列表的指定位置
* @param index -指定的添加位置
* @param c-要添加到此列表的元素的集合
* @return 若集合中的元素个数为0,则返回false,否则,返回true
*/
public boolean addAll(int index,Collection c){
rangeCheckForadd(index);//判断指定位置的索引是否越界
Object a[]=c.toArray();//获取集合中的所有元素
int newNum=a.length;//获取数组a的长度
ensureExplicitCapacity(size+newNum);//判断是否需要扩容
System.arraycopy(elementData,index,elementData,index+a.length,size-index);//将此列表中指定位置的元素以及其后面的元素向后移动数组a的长度
System.arraycopy(a,0,elementData,index,newNum);//将数组a中的元素从指定位置开始全部添加到此列表中
size+=newNum;//将列表的大小更新
return newNum!=0;
}
/**
* @param min -列表的大小加一
*/
private void ensureCapacityInternal(int min){
ensureExplicitCapacity(calculateCapacity(elementData, min));
}
/**
* 判断数组是否需要扩容
* @param min-最小元素的容纳量
*/
private void ensureExplicitCapacity(int min){
if(min-elementData.length>0){//若当前数组的长度大于数组的容量,则进行扩容操作
grow(min);
}
}
/**
* 判断指定位置的索引是否越界
* @param index-指定位置的索引
*/
public void rangeCheckForadd(int index){
if(index<0||index>size){
throw new IndexOutOfBoundsException();
}
}
/**
* @param elementData -当前数组
* @param min
* @return min
*/
private static int calculateCapacity(Object[] elementData,int min){
if(elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA){
return Math.max(min,DEFAULT_CAPACITY);//若数组调用无参构造,则返回数组当前长度加一和DEFAULT_CAPACITY空数组容量的较大值
}
return min;
}
/**
* 数组扩容
* @param min
*/
private void grow(int min){
int oldCapacity=elementData.length;//获取原先数组的容量
int newCapacity=oldCapacity + (oldCapacity >> 1);//将新的容量扩大到原来的1.5倍
if(newCapacity-min<0){//若扩容后数组的容量小于当前数组的长度加一,则新的容量改为当前数组的长度加一
newCapacity=min;
}
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
部分自定义的ArrayList及源码的理解
于 2022-04-24 19:09:06 首次发布