ArrayList
- 可以为空
- 允许重复数据
- 有序
- 非线程安全
添加
只有add和remove和clear能改变 Arraylist的size,并且在添加或者插入元素时元素时会判断size符不符合要求,不符合要求就会抛出错误,手动加入null实现增加size才能实现隔空插入元素,并且在指定位置插入元素,该位置及后面的所有元素往后退一个,这两点和数组不太一样
private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
List泛型的好处:
通过允许指定泛型类或方法操作的特定类型,泛型功能将类型安全的任务从您转移给了编译器。不需要编写代码来检测数据类型是否正确,因为会在编译时强制使用正确的数据类型。减少了类型强制转换的需要和运行时错误的可能性。泛型提供了类型安全但没有增加多个实现的开销。
扩容
构造ArrayList的时候,默认的底层数组大小是10,
扩容的时候把元素组大小先乘以3再除以2最后再-1(1.5倍)(jdk1.6)(在jdk1.6之后,是原数组长度+(原数组长度)/2);
删除元素
1.按照下标删除
2.按照元素删除,与指定元素匹配的第一个元素。
这两种方法删除后,该位置后面的元素都会往前移动填满。
ArrayList优缺点
优点
1.底层以数组实现,是随机访问模式,实现了RandomAccess接口,查找非常快;
2.顺序添加元素时非常方便,只是数组里面添加了一个元素。
缺点:
1.删除 和 插入指定位置元素的时候涉及到复制元素,涉及的元素很多的话比较耗费性能;
ArrayList 和Vector区别
ArrayList是线程不安全的,因为它的所有方法都不同步。可以用Collection.synchronzedList把ArrayList变成线程安全的List:
List<String> synchronizedList = Collections.synchronizedList(list);
synchronizedList.add("aaa");
synchronizedList.add("bbb");
for (int i = 0; i < synchronizedList.size(); i++)
{
System.out.println(synchronizedList.get(i));
}```
Vector
1.Vector是ArrayList的线程安全版本,其实现90%和ArrayList都完全一样
2.Vector可以指定增长因子,如果不指定那就是*2.
```java
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
不考虑并发问题,仅限于单线程中使用,Vector和ArrayList的效率基本上是一样的。
之所以说基本上,是因为Vector对每个方法都做了synchronized操作,有synchronized关键字意味着,在每个方法的开始和结束会给对象添加Monitor和释放Monitor,这当然会有一定效率上的损失。不过,在Java和CPU发展的今天,这点效率上的损失完全可以忽略不计。
为什么ArrayList的elementData是用transient修饰的?
ArrayList实现了Serializable接口,这意味着ArrayList是可以被序列化的,用transient修饰elementData意味着我不希望elementData数组被序列化。这是为什么?因为序列化ArrayList的时候,ArrayList里面的elementData未必是满的,比方说elementData有10的大小,但是我只用了其中的3个,那么是否有必要序列化整个elementData呢?显然没有这个必要,因此ArrayList中重写了writeObject方法。
学习ArrayList笔记,原文在
https://www.cnblogs.com/xrq730/p/4989451.html