标签:子类 ArrayList elementData List add 数组 public
ArrayList子类
ArrayList是List子接口使用最多的一个子类,但是这个子类在使用的时候也是有前提要求的。
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
范例:使用ArrayList存储数据
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo {
public static void main(String[] args) {
List<String> all = new ArrayList<String>(); //为List父接口进行实例化
all.add("Hello");
all.add("Hello"); //重复数据
all.add("Word!");
System.out.println(all);
}
}
通过本程序可以发现List存储的特征:
- 保存的顺序就是存储顺序
- List的集合里面允许存在重复数据
在以上的程序里面虽然实现了集合的输出,但是这种输出的操作是直接利用了每一个类提供的toString()方法实现的,为了方便的进行输出处理,在JDK1.8之后,Iterable父接口之中定义有一个forEach()方法,这个方法的定义如下:
- 输出支持:default void forEach(Consumer<? super T> action);
范例:利用forEach()方法输出(不是标准输出)
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo {
public static void main(String[] args) {
List<String> all = new ArrayList<String>(); //为List父接口进行实例化
all.add("Hello");
all.add("Hello"); //重复数据
all.add("Word!");
all.forEach((str)->{
System.out.println(str + "、");
});
}
}
需要注意的是,此种输出并不是在正常开发情况下要考虑的操作形式。
范例:观察List集合的其他操作方法
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo {
public static void main(String[] args) {
List<String> all = new ArrayList<String>(); //为List父接口进行实例化
System.out.println("集合是否为空?"+all.isEmpty());
all.add("Hello");
all.add("Hello"); //重复数据
all.add("Word!");
all.remove("Hello"); //删除元素(顺序删除)
System.out.println("集合元素个数:"+all.size());
all.forEach((str)->{
System.out.println(str + "、");
});
}
}
集合是否为空?true
集合元素个数:2
Hello、
Word!、
如果以方法的功能为例,那么ArrayList里面的操作支持与之前编写的链表形式是非常相似的,但是它并不是使用链表来实现的,通过类名称就可以发现ArrayList应该封装的是一个数组。
//无参构造方法
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//有参构造
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) { //如果容量大于0就实例化数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//transient Object[] elementData; 不能被序列化
//private static final Object[] EMPTY_ELEMENTDATA = {};
通过有参构造方法可以发现,在ArrayList里面包含的数据实际上就是一个对象数组,如果现在在进行数据追加的时候发现ArrayList集合里面保存的对象数组的长度不够的时候会进行新的数组开辟,同时将原始的旧数组内容拷贝到新数组之中。
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
oldCapacity >> 1 /* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
如果在实例化ArrayList类对象的时候并没有传统初始化的长度,则默认会使用一个空数组,但是如果在进行数据增加的时候发现数组容量不够了,则会判断当前容量与默认的容量大小,使用较大的一个数值进行新的数组开辟,由此可以得出一个结论:
- JDK1.9之后:ArrayList默认的构造只会使用默认的空数组,使用的时候才会开辟数组,默认的开辟长度为10.
- JDK1.9之前:AarrayList默认的构造实际上就会默认开辟大小为10的数组。
当ArrayList保存的容量不足的时候会采用成倍增长。
在使用ArrayList子类的时候一定要估算出你的数据量会有多少,如果超过了10个,那么通过有参构造方法进行创建,以避免垃圾数组空间的产生。
标签:子类,ArrayList,elementData,List,add,数组,public 来源: https://blog.csdn.net/weixin_46245201/article/details/113572495
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。