ArrayList
ArrayList
说明
ArrayList是List的一个实现类,底层是数组,查询快,增删慢,线程不安全
实践
class Student {
    String name;
    Integer age;
    public Student() {
    }
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public Integer getAge() {
        return age;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Student student = (Student) o;
        return Objects.equals(name, student.name) && Objects.equals(age, student.age);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
package com.qianfeng.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
/**
 * 功能描述
 *
 * @since 2022-05-07
 */
public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<Object> arrayList = new ArrayList<>();
        Student s1 = new Student("张三", 10);
        Student s2 = new Student("李四", 11);
        Student s3 = new Student("王五", 12);
        // 添加元素
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        arrayList.add(s3);
        System.out.println(arrayList);
        // 删除元素
        arrayList.remove(new Student("李四", 11));
        System.out.println(arrayList);
        //遍历
        System.out.println("==============迭代器遍历================");
        Iterator it = arrayList.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        System.out.println("==============迭代器遍历================");
        ListIterator lit = arrayList.listIterator();
        while (lit.hasNext()) {
            System.out.println(lit.next());
        }
        System.out.println("==============迭代器遍历逆序================");
        while (lit.hasPrevious()) {
            System.out.println(lit.previous());
        }
        //判断
        System.out.println(arrayList.isEmpty());
        System.out.println(arrayList.contains(new Student("王五", 12)));
        //定位
        System.out.println(arrayList.indexOf(new Student("王五", 12)));
    }
}
源码分析
带着疑问看源码
1.ArrayList底层是数组,数组的大小在初始化的时候确定,初始的尺寸如何确定?扩容如何实现?缩容呢?
数组的大小即容量
容量:
当ArrayList中没有数据时,容量为0,添加一个数据后,容量为10,元素数量超出容量后进行扩容,每次扩容为原来的1.5倍
初始参数
DEFAULT_CAPACITY = 10; //初始容量是10
transient Object[] elementData; //数据最终存储在该数组内 
private int size; // ArrayList包含元素的个数
arrayList.add()源码分析
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
// 扩容的核心代码
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    // 扩容每次扩原来容量的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    // 首次扩容时扩容到10
    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);
}
remove方法源码分析
看完源码可以得出 ArrayList没有自动缩容的机制,想要缩容需要手动调用trimToSize方法
public E remove(int index) {
    // index范围检查
    rangeCheck(index);
    modCount++;
    E oldValue = elementData(index);
    int numMoved = size - index - 1;
    // 调用本地方法实现数组的拷贝,将index+1及后面的元素移动到index处
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                            numMoved);
    elementData[--size] = null; // clear to let GC do its work
    return oldValue;
}
trimToSize 手动缩容即直接缩容至当前集合包含的元素个数
public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = (size == 0)
            ? EMPTY_ELEMENTDATA
            : Arrays.copyOf(elementData, size);
    }
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号