ArrayList集合源码解读

ArrayList特点:查询快、有序、自动扩容、元素可为空,源码解读从构造方法开始:ArrayList支持三种构造方式:

 //初始化指定集合大小
 public ArrayList(int var1) {
     if (var1 > 0) {
         this.elementData = new Object[var1];
     } else {
           
         //集合大小不能小于0
         if (var1 != 0) {
             throw new IllegalArgumentException("Illegal Capacity: " + var1);
         }
         this.elementData = EMPTY_ELEMENTDATA;
     }
}
//不指定集合大小,默认为空数组
public ArrayList() {
     this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//初始化指定某个集合,将形参集合传递给ArrayList的数组
public ArrayList(Collection<? extends E> var1) {
        this.elementData = var1.toArray();
        if ((this.size = this.elementData.length) != 0) {
            if (this.elementData.getClass() != Object[].class) {
                this.elementData = Arrays.copyOf(this.elementData, this.size, Object[].class);
            }
        } else {
            this.elementData = EMPTY_ELEMENTDATA;
        }
}

接着就是ArrayList常见的几个方法:获取集合大小、集合是否为空、是否包含某元素、转换为数组,都很简单:

public int size() {
	return this.size;
}

public boolean isEmpty() {
	return this.size == 0;
}

public boolean contains(Object var1) {
	return this.indexOf(var1) >= 0;
}

public int indexOf(Object var1) {
	int var2;
	if (var1 == null) {
		for(var2 = 0; var2 < this.size; ++var2) {
			if (this.elementData[var2] == null) {
				return var2;
			}
		}
	} else {
		for(var2 = 0; var2 < this.size; ++var2) {
			if (var1.equals(this.elementData[var2])) {
				return var2;
			}
		}
	}

	return -1;
}

public Object[] toArray() {
    return Arrays.copyOf(this.elementData, this.size);
}

再接下来就是get获取元素方法了,get方法里面做了两个事情,先检查数组下标是否越界,越界直接抛异常,否则根据下标从数组中获取元素:

public E get(int var1) {
	this.rangeCheck(var1);
	return this.elementData(var1);
}

private void rangeCheck(int var1) {
   if (var1 >= this.size) {
	   throw new IndexOutOfBoundsException(this.outOfBoundsMsg(var1));
   }
}

接着是add方法,add方法里做了两个事:若为空数组,则初始化为大小为10,再确定数组的容量是否需要扩容,扩容为(原容量+原容量/2),接着在数组的(size+1)位置上放入新增的元素:

public boolean add(E var1) {
	this.ensureCapacityInternal(this.size + 1);
	this.elementData[this.size++] = var1;
	return true;
}

private void ensureCapacityInternal(int var1) {
	//注意空数组的特殊情况,将数组大小赋为10了
	if (this.elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
		var1 = Math.max(10, var1);
	}

	this.ensureExplicitCapacity(var1);
}

private void ensureExplicitCapacity(int var1) {
        //modCount防止并发修改
	++this.modCount;
	//这个地方要注意:this.elementData在第一次add时候大小赋值为了10
	if (var1 - this.elementData.length > 0) {
		this.grow(var1);
	}

}

private void grow(int var1) {
	int var2 = this.elementData.length;
	//扩容为(原容量+原容量/2)
	int var3 = var2 + (var2 >> 1);
	if (var3 - var1 < 0) {
		var3 = var1;
	}

	if (var3 - 2147483639 > 0) {
		var3 = hugeCapacity(var1);
	}

	this.elementData = Arrays.copyOf(this.elementData, var3);
}

private static int hugeCapacity(int var0) {
	if (var0 < 0) {
		throw new OutOfMemoryError();
	} else {
		return var0 > 2147483639 ? 2147483647 : 2147483639;
	}
}

以上便是ArrayList的核心代码了,比较简单,如果别人面试时让你实现一个ArrayList,可千万别说不会,会被看扁的~

后面有空再补充一些吧~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值