Arrays.copyOf() 方法理解

最近看线性表、栈、队列数据结构实现源码时,经常看到 Arrays.copy()、System.arraycopy() 方法。

在JDK 6中,Arrays 类别 新增了copyOf()方法. Array.copyOf() 用于复制指定的数组内容以达到扩容的目的,该方法对不同的基本数据类型都有对应的重载方法,详见 java api:

 public static  T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
 }


public static  T[] copyOf(U[] original, int newLength, Class newType) {
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
}

从代码可知,数组拷贝时调用的是本地方法 System.arraycopy() ;
Arrays.copyOf()方法返回的数组是新的数组对象,原数组对象仍是原数组对象,不变,该拷贝不会影响原来的数组。copyOf()的第二个自变量指定要建立的新数组长度,如果新数组的长度超过原数组的长度,则保留数组默认值.

import java.util.Arrays;

public class ArrayDemo {
	public static void main(String[] args) {
        int[] arr1=new int[]{2,5,6,0,0,0};
        int[] arr2=new int[]{1,3,4};
//        Object src,  int  srcPos,
//        Object dest, int destPos,
//        int length
        System.arraycopy(arr2,0,arr1,arr2.length,arr2.length);
        Arrays.sort(arr1);
        System.out.println(Arrays.toString(arr1));
	}
} 

输出:   [1, 2, 3, 4, 5, 6]

public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

参数说明:
src:源对象
srcPos:源数组中的起始位置
dest:目标数组对象
destPos:目标数据中的起始位置
length:要拷贝的数组元素的数量

 

System.arraycopy() 源码如下:

public class ArraycopyTest{

    public static void main(String[] args){
        char[] c1 = new String("123456").toCharArray();
        char[] c2 = new String("abcdef").toCharArray();
        System.arraycopy(c1, 2, c2, 1, 2);
        System.err.println(Arrays.toString(c1));
        System.err.println(Arrays.toString(c2));
    }

}

输出:     [1, 2, 3, 4, 5, 6]
             [a, 3, 4, d, e, f]

 

1> 普通增加

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

2> 指定位置添加

public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
}

 

                    在index=2的位置添加新元素

Arrays.copyOf() 方法理解_第1张图片

3> 删除指定位置元素

   public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

Arrays.copyOf() 方法理解_第2张图片

4> 删除指定元素 (和上面删除指定索引的实现是一样的)

  注意: 如果要删除的元素在集合中有多个 那么不能全删除掉,此时应该使用倒序遍历删除

public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

    /*
     * Private remove method that skips bounds checking and does not
     * return the value removed.
     */
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
    }

 

 

 

 

 

 

你可能感兴趣的:(JAVA编程相关)