您的位置:

Java ArrayList

ArrayList是Java集合框架中的一种动态数组,它位于java.util包下。与传统的数组相比,它具有更多的方法,方便了数组的操作和处理。ArrayList的大小动态改变,可以按照需求添加和删除元素,同时它还实现了List接口,可以进行线性操作。以下是对Java ArrayList的详细阐述。

一、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进行比较后选择更适合的容器。