欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java数组增加元素的方法(用java写数组并循环输入数据)

程序员文章站 2023-11-21 11:14:04
一、概述对于java开发而言,使用集合那是家常便饭的事情,这其中arraylist可能是使用比较多了,用起来也是相当的简单,通常就是new一个arraylist,然后往里面添加元素,但是你真的了解往里...

一、概述

对于java开发而言,使用集合那是家常便饭的事情,这其中arraylist可能是使用比较多了,用起来也是相当的简单,通常就是new一个arraylist,然后往里面添加元素,但是你真的了解往里面添加元素的时候,其内部发生了什么吗?

java数组增加元素的方法(用java写数组并循环输入数据)

二、源码解读

1、相关的内部参数default_capacity:默认初始容量empty_elementdata:空实例对象的默认数组defaultcapacity_empty_elementdata:与empty_elementdata类似,主要用于区分在首次添加元素时判断如何进行扩容elementdata:arraylist中实际存储元素的object数组size:arraylist中实际包含的元素数量
2、构造函数

arraylist()

执行第一行代码的时候,有如下操作:

就是将arraylist的elementdata引用指向内置的默认对象数组。

public arraylist(int initialcapacity)

  1. 如果传入的容量大小大于0,则将内置的elementdata指向一个新的object数组(数组大小为initialcapacity)
  2. 如果initialcapacity值为0,则将elementdata引用指向empty_elementdata这个内部object数组。
  3. 如果以上两者均不满足的话,则会抛出illegalargumentexception并附带initialcapacity参数。

3、add方法解析

add(e, e)

我们首先来看下这个方法

我们先跳过第一行代码,看第二行,它执行的是将elementdata数组中size++位置的元素指定为传入的参数,在最开始我们就知道,size是数组的实际大小,这就非常好理解了,它执行了size++后,那elementdata[size]++这个位置就是数组中的最后一个位置了,因此也就有了添加在最末尾的效果,添加成功后,第三行返回true,这没什么好说的,重点来看下第一行,ensurecapacityinternal这个方法,代码如下:

 private void ensurecapacityinternal(int mincapacity) {
 		if (elementdata == defaultcapacity_empty_elementdata) {
			 mincapacity = math.max(default_capacity, mincapacity);
 }

 ensureexplicitcapacity(mincapacity);
 }

首先,判断elementdata存的是否是空数组,如果是,则需要的容量就是默认容量,也就是10,接下来就执行ensureexplicitcapacity,来判断是否需要扩容。我们来看下这个方法:

 private void ensureexplicitcapacity(int mincapacity) {
 modcount++;

 // overflow-conscious code 注意这个注释
 if (mincapacity - elementdata.length > 0)
 grow(mincapacity);
 }

很明显,grow方法就是那个扩容方法,什么时候执行呢?就是当需要的最小容量比现在存得数组的长度大的时候,需要进行扩容。这个有地方需要思考下,就是mincapacity – elementdata.length > 0是不是能换成mincapacity > elementdata.length这种写法呢?

我们再来看下grow方法:

 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.5倍得到新的容量值,(oldcapacity >> 1这个右移一位就是除以2),然后再判断扩大后的容量是不是小于需要的最小容量,是的话,将最小容量赋值给新的容量值,不然的话判断新的容量值是否大于max_array_size这个值,是的话,将hugecapacity的返回值赋给新的容量值,我们来看下hugecapacity方法:

 private static int hugecapacity(int mincapacity) {
 if (mincapacity < 0) // overflow
 throw new outofmemoryerror();
 return (mincapacity > max_array_size) ?
 integer.max_value :
 max_array_size;
 }

这边可以看出来,如果需要的最小容量小于0,抛出异常,否则如果需要的最小容量大于max_array_size,则取integer.max_value,否则取max_array_size。

这个就是arraylist执行add的过程,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时,才真正分配容量。每次按照1.5倍(位运算)的比率通过copeof的方式扩容。