System.arraycopy实现数组扩容,ArrayList阅读记录

博客探讨了Java中如何通过`System.arraycopy`实现数组扩容,以ArrayList为例详细阐述其内部机制。还提及了ArrayList中的Iterator接口和RandomAccess接口的重要性,建议根据List类型选择合适的遍历方式以优化性能。此外,解释了ArrayList中`transient`关键字的使用,用于避免特定成员变量在序列化过程中被持久化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组被定义以后不能再将length重新增大,但我们可以是有拷贝的方法进行扩容。
主要使用的函数——

System.arraycopy(arr3, insertedIndex, arr3, insertedIndex + 1, elementCounts - insertedIndex);      
//把索引为insertedIndex位置开始的elementCounts个元素数据复制到arr3的insertedIndex + 1的位置上。

扩容实现Array类:

          resourceObjs = Arrays.copyOf(resourceObjs, _zoomSize);// 可以按_zoomSize倍数进行扩容

下面是一个具体的实现方法,ArrayList的实现,扩容是当中的一个重要内容。


import java.util.Arrays;

public class VariableArray {

    private static final int DEFALUT_LENGTH = 5;
    private Object[] resourceObjs;
    private int count = 0;

    public VariableArray(){
        resourceObjs = new Object[DEFALUT_LENGTH];
    }

    public void appendNewObject(Object obj){// 每次扩容1,并做新对象的添加
        int oldLength = resourceObjs.length;
        if (oldLength - 1 < count){
            int _zoomSize = oldLength + 1;
            ensureCapacity(_zoomSize);
        }
        resourceObjs[count] = obj;
        count++;
        System.out.println(Arrays.toString(resourceObjs));
    }

    private void ensureCapacity(int _zoomSize){
          resourceObjs = Arrays.copyOf(resourceObjs, _zoomSize);// 可以按_zoomSize倍数进行扩容
    }

    public void testSystemArrayCopy(){
        int[] arr0 = {1, 3, 5, 7, 9};
        int[] arr2 = {2, 4, 6, 8, 10, 12, 14};
        int insertedIndex = 4;
        int insertedData = 999;

        System.arraycopy(arr0, 0, arr2, 0, arr0.length);
        System.out.println(Arrays.toString(arr2));// [1, 3, 5, 7, 9, 12, 14]

        Integer[] arr1 = {2, 4, 6, 8, 10, 12, 14};
        System.out.println(Arrays.toString(arr1));

        int _zoomSize = arr1.length + 1;
        Integer[] arr3 = Arrays.copyOf(arr1, _zoomSize);
        int elementCounts = arr3.length - 1;
        //把索引为insertedIndex位置开始的elementCounts个元素数据复制到arr3的insertedIndex + 1的位置上。
        System.arraycopy(arr3, insertedIndex, arr3, insertedIndex + 1, elementCounts - insertedIndex);      
        arr3[insertedIndex] = insertedData;
        System.out.println(Arrays.toString(arr3));
    }

}

下面给出关于ArrayList解读的一些内容点
Iterator接口:

public interface Iterator<E> {
    public boolean hasNext();
    public E next();
    public void remove();
}

RandomAccess接口说明:
JDK中推荐的是对List集合尽量要实现RandomAccess接口
如果集合类是RandomAccess的实现,则尽量用for(int i = 0; i < size; i++) 来遍历而不要用Iterator迭代器来遍历,
在效率上要差一些。反过来,如果List是Sequence List,则最好用迭代器来进行迭代。

在对List的遍历算法中,要尽量来判断是属于RandomAccess(如ArrayList) 还是Sequence List (如LinkedList),因为适合RandomAccess List的遍历算法,用在Sequence List上就差别很大,常用的作法就是:

    if (list instance of RandomAccess) {
        for(int m = 0; m < list.size(); m++){}
    }else{
        Iterator iter = list.iterator();
        while(iter.hasNext()){}
    }

ArrayList类中使用transient定义成员属性,因为ArrayList继承了Serializable接口,做了持久化,transient的目的就是不希望所定义的常量不被进行持久化
transient Object[] array;

————————————————————————————————————————————————————————————

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {...}
public abstract class AbstractCollection<E> implements Collection<E> {...}


public interface Collection<E> extends Iterable<E> {
    public boolean add(E object);
    public boolean addAll(Collection<? extends E> collection);
    public void clear();
    public boolean contains(Object object);
    public boolean containsAll(Collection<?> collection);
    public boolean equals(Object object);
    public int hashCode();
    public boolean isEmpty();
    public Iterator<E> iterator();
    public boolean remove(Object object);
    public boolean removeAll(Collection<?> collection);
    public boolean retainAll(Collection<?> collection);
    public int size();
    public Object[] toArray();
    public <T> T[] toArray(T[] array);
}

public interface Iterable<T> {
    /**
     * Returns an {@link Iterator} for the elements in this object.
     *
     * @return An {@code Iterator} instance.
     */
    Iterator<T> iterator();
}


public interface List<E> extends Collection<E> {...}
当中定义有public ListIterator<E> listIterator();故而可以有前一个和后一个元素的判断:
 void add(E object);
ListIterator接口方法:
    /**
     * Returns whether there are more elements to iterate.
     *
     * @return {@code true} if there are more elements, {@code false} otherwise.
     * @see #next
     */
    public boolean hasNext();

    /**
     * Returns whether there are previous elements to iterate.
     *
     * @return {@code true} if there are previous elements, {@code false}
     *         otherwise.
     * @see #previous
     */
    public boolean hasPrevious();

    /**
     * Returns the next object in the iteration.
     *
     * @return the next object.
     * @throws NoSuchElementException
     *             if there are no more elements.
     * @see #hasNext
     */
    public E next();

    /**
     * Returns the index of the next object in the iteration.
     *
     * @return the index of the next object, or the size of the list if the
     *         iterator is at the end.
     * @throws NoSuchElementException
     *             if there are no more elements.
     * @see #next
     */
    public int nextIndex();

    /**
     * Returns the previous object in the iteration.
     *
     * @return the previous object.
     * @throws NoSuchElementException
     *             if there are no previous elements.
     * @see #hasPrevious
     */
    public E previous();

    /**
     * Returns the index of the previous object in the iteration.
     *
     * @return the index of the previous object, or -1 if the iterator is at the
     *         beginning.
     * @throws NoSuchElementException
     *             if there are no previous elements.
     * @see #previous
     */
    public int previousIndex();

    /**
     * Removes the last object returned by {@code next} or {@code previous} from
     * the list.
     *
     * @throws UnsupportedOperationException
     *             if removing is not supported by the list being iterated.
     * @throws IllegalStateException
     *             if {@code next} or {@code previous} have not been called, or
     *             {@code remove} or {@code add} have already been called after
     *             the last call to {@code next} or {@code previous}.
     */
    public void remove();

    /**
     * Replaces the last object returned by {@code next} or {@code previous}
     * with the specified object.
     *
     * @param object
     *            the object to set.
     * @throws UnsupportedOperationException
     *             if setting is not supported by the list being iterated
     * @throws ClassCastException
     *             if the class of the object is inappropriate for the list.
     * @throws IllegalArgumentException
     *             if the object cannot be added to the list.
     * @throws IllegalStateException
     *             if {@code next} or {@code previous} have not been called, or
     *             {@code remove} or {@code add} have already been called after
     *             the last call to {@code next} or {@code previous}.
     */
    void set(E object);
ArrayList接口构造函数
 public ArrayList(int capacity) {
    if (capacity < 0) {
        throw new IllegalArgumentException("capacity < 0: " + capacity);
    }
    array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]);
}// 构造含有容量大小的对象

 public ArrayList() {
    array = EmptyArray.OBJECT;
}// 构造具有初始化大小的对象
_________________________________________________________________________________________________________
   @Override 
   public boolean add(E object) {
        Object[] a = array;
        int s = size;
        if (s == a.length) {// 扩容逻辑
            Object[] newArray = new Object[s +
                    (s < (MIN_CAPACITY_INCREMENT / 2) ?
                     MIN_CAPACITY_INCREMENT : s >> 1)];
            System.arraycopy(a, 0, newArray, 0, s);
            array = a = newArray;
        }
        a[s] = object;// 将数组中的最后一个位置进行赋值,完成添加
        size = s + 1;
        modCount++;
        return true;
    }
_________________________________________________________________________________________________________
插入数据到具体某个位置,有扩容和移位的逻辑处理


    @Override public void add(int index, E object) {
    Object[] a = array;
    int s = size;
    if (index > s || index < 0) {
        throwIndexOutOfBoundsException(index, s);
    }                                                 if (s < a.length) {
        System.arraycopy(a, index, a, index + 1, s - index);
    } else {
        // assert s == a.length;
        Object[] newArray = new Object[newCapacity(s)];
        System.arraycopy(a, 0, newArray, 0, index);
        System.arraycopy(a, index, newArray, index + 1, s - index);
        array = a = newArray;
    }
    a[index] = object;
    size = s + 1;
    modCount++;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值