一、ArrayList特点
1、动态数组:ArrayList是基于数组实现,但是比传统数组要灵活,可以根据实际需要不断增加元素数量。
2、支持泛型:可以指定ArrayList存储的元素类型(如String、Integer等)。
3、可变长度:ArrayList的长度是可以随意增加或减少的,因此可以动态地添加、删除元素,而不会浪费内存空间。
4、线程不安全:ArrayList不是线程安全的,即在多线程环境下会出现并发问题。
二、ArrayList的基本使用
1、创建ArrayList:通过关键字new来创建ArrayList。
List<String> list = new ArrayList<String>();
2、添加元素:使用add方法添加元素。
list.add("Java");
list.add("Python");
list.add("C++");
list.add("Javascript");
3、获取元素:通过索引获取元素,索引从0开始。
String element = list.get(0);
4、修改元素:通过索引来修改元素。
list.set(0, "HTML");
5、删除元素:通过索引来删除元素。
list.remove(0);
6、遍历元素:使用for-each循环遍历ArrayList。
for(String element : list){
System.out.println(element);
}
三、ArrayList的扩容机制
ArrayList是一个动态数组,它可以根据需要动态增加和删除元素。但是,在实现时需要考虑到如何处理内存空间,避免不必要的内存浪费。
当ArrayList的容量不能满足当前元素数量时,会自动进行扩容。扩容机制如下:
1、计算当前ArrayList的容量是否已满;
2、如果容量已满,会将当前容量增加一倍,并将原来的数组内容复制到新的数组中;
3、如果新容量还不够用,重复以上操作。
private void ensureCapacityInternal(int minCapacity){
// 如果ArrayList还没有创建
if(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA){
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity){
modCount++;
// 如果当前ArrayList的数据量已经超过它的容量了,需要扩容
if(minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity){
//原容量
int oldCapacity = elementData.length;
//新容量 = old(原容量) * 1.5
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果新容量还不够用,就需要进行一次调整
if(newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果newCapacity大于MAX_ARRAY_SIZE,会抛出异常
if(newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//将原有的数组复制到新数组中
elementData = Arrays.copyOf(elementData, newCapacity);
}
四、ArrayList的线程不安全和线程安全方法
1、线程不安全:ArrayList是线程不安全的,若要在线程安全的情况下使用ArrayList,需要使用线程安全的容器CopyOnWriteArrayList。
2、线程安全方法:可以通过synchronized关键字来保证并发下的线程安全。
public void synchronized addToArrayList(){
list.add("Java");
}
五、ArrayList与LinkedList的比较
1、存储方式:ArrayList是数组存储,LinkedList是链表存储。
2、插入和删除操作:LinkedList的插入和删除效率比ArrayList高。
3、随机访问:ArrayList比LinkedList高效,因为它基于数组实现,可以通过下标进行随机访问。
综上所述,ArrayList在存取元素方面具有优势,而LinkedList在插入和删除元素方面具有优势。
六、总结
Java ArrayList是一种非常常用的动态数组,可以根据需要动态增加或删除元素。ArrayList支持泛型,可以指定存储的元素类型。在实现时需要考虑到ArrayList的扩容机制和线程安全问题,并且跟LinkedList进行比较后选择更适合的容器。