数组复制,扩容的几个容易搞混的方法

几个数组方法搞的我头晕, 记不住,就直接写下来了。

1、 先来一个底层方法:

System.arraycory(源数组,源数组开始位置,目标数组,目标数组开始位置, 复制的长度)

*这个方法,每次看着看着就有晕了过去,参数太多,类型又差不多,总是会看偏,理解错。 其实,System类的源码,解释的还是很清楚的*

源码+注释:

   /**
     * @param      src      the source array. 源数组
     * @param      srcPos   starting position in the source array. 源数组复制的开始位置
     * @param      dest     the destination array.  目标数组
     * @param      destPos  starting position in the destination data. 目标数组接收的开始位置
     * @param      length   the number of array elements to be copied.  被复制的元素的长度
     * @exception  IndexOutOfBoundsException  if copying would cause
     *               access of data outside array bounds.  下标越界
     * @exception  ArrayStoreException  if an element in the <code>src</code>
     *               array could not be stored into the <code>dest</code> array
     *               because of a type mismatch.  两数组类型不匹配
     * @exception  NullPointerException if either <code>src</code> or
     *               <code>dest</code> is <code>null</code>.
     */
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

,看到这里应该有个七八分的理解了,  下面直接上示例代码,进一步说明一下 示例1:

public class ArrayCopy {

    public static void main(String[] args) {

        //源数组
        int[] arr = {10,30,40,20,80};
        //调用复制方法
        int[] newArr = arrcopy(arr,10);
        System.out.println(Arrays.toString(newArr));  
    }
    public static int[] arrcopy(int[] original, int newLength ){
        int [] newArr = new int[newLength];
        System.arraycopy(original, 0,newArr, 0, Math.min(original.length,newLength));
        return newArr;

    }
}

结果:[10, 30, 40, 20, 80, 0, 0, 0, 0, 0]。

这里可以看到, System.arraycopy(), 方法的最后一个参数,用到了Math,min(), 方法;Math.min(A,B),表示取两者中最小的那个数。 为什么会添加这个方法呢?

因为会存在这样的情况:当被复制的元素的长度 ,大于目标数组时,会报错:java.lang.ArrayIndexOutOfBoundsException

数组下标越界。 所以为了避免这样的情况,就添加了Math.min(),方法。  示例2:

  //定义 两个数组,(这里为了方便观察,就用int型数组了)
        int[] int1 = {1,2,4,5,6,7,8,9,10};
        int[] int2 = new int[3];

        //调用方法
       System.arraycopy(int1,0,int2,0,int1.length);

目标数组的长度只有3, 源数组的长度是10, 如上面,如果被复制的元素长度是整个源数组的长度,那么,目标数组容量肯定不够的。

然而: 当添加了Math.min(), 方法后,示例1,也变成了一个截取数组的方法了:

public class ArrayCopy {

    public static void main(String[] args) {

        //源数组
        int[] arr = {10,30,40,20,80};
        //调用复制方法,新数组length=4
        int[] newArr = arrcopy(arr,4);
        System.out.println(Arrays.toString(newArr));
    }
    public static int[] arrcopy(int[] original, int newLength ){

        int [] newArr = new int[newLength];
        System.arraycopy(original, 0,newArr, 0, Math.min(original.length,newLength));
        return newArr;

    }
}

结果: [10, 30, 40, 20]。    **变成了截取源数组的方法了**

===================================================================

2、数组工具类Arrays.copyof(Object [] array, int  length);

如果理解了上面的那个底层方法后, 我想,看一下这个方法的源码,肯定就知道怎么回事了。 

源码:

    /**
     *
     * @param original the array to be copied   被复制数组
     * @param newLength the length of the copy to be returned 反对的数组的长度
     * @return a copy of the original array, truncated or padded with zeros
     *     to obtain the specified length
     * @throws NegativeArraySizeException if <tt>newLength</tt> is negative
     * @throws NullPointerException if <tt>original</tt> is null
     * @since 1.6
     */
    public static int[] copyOf(int[] original, int newLength) {
        int[] copy = new int[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

是不是很惊喜, 它的底层实现竟然是 system.arraycopy(), 方法。 同时也运用了Math.min(), 也就是说可以实现扩容和缩容两种操作。

示例:

public class ArrayCopyTwo {

    public static void main(String[] args) {

        int[] arr = {10,20,30,40,50,60};

        arr = Arrays.copyOf(arr,10);
        System.out.println("第一次扩容,arr: "+Arrays.toString(arr));
        
        //结果: 第一次扩容,arr: [10, 20, 30, 40, 50, 60, 0, 0, 0, 0]
       

        arr = Arrays.copyOf(arr,3);
        System.out.println("第二次缩容,arr:"+Arrays.toString(arr));
        
        //结果:  第二次缩容,arr:[10, 20, 30]
    }

}

========================================================================

3、数组截取方法: Arrays.copyOfRang(int[] arr, int from, int to );

这个方法是截取(或者叫复制) 源数组 arr,  在 [from,to) 范围内的元素。  同样先来看源码:

   /**
     * @param original the array from which a range is to be copied
     * @param from the initial index of the range to be copied, inclusive
     * @param to the final index of the range to be copied, exclusive.
     *     (This index may lie outside the array.)
     * @return a new array containing the specified range from the original array,
     *     truncated or padded with zeros to obtain the required length
     * @throws ArrayIndexOutOfBoundsException if {@code from < 0}
     *     or {@code from > original.length}
     * @throws IllegalArgumentException if <tt>from > to</tt>
     * @throws NullPointerException if <tt>original</tt> is null
     * @since 1.6
     */
    public static int[] copyOfRange(int[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        int[] copy = new int[newLength];
        System.arraycopy(original, from, copy, 0,
                         Math.min(original.length - from, newLength));
        return copy;
    }

正如你看到的, 它的底层又是这个方法:System.arraycopy().  不同的只是参数的值。这里就不再讲了。

示例:

public class ArrayCopyTwo {

    public static void main(String[] args) {

        int[] arr2 = {10,20,30,40,50,60};
        arr2 = Arrays.copyOfRange(arr2,2,5);
        System.out.println("范围内复制:"+Arrays.toString(arr2));
        
        // 结果: 范围内复制:[30, 40, 50]
    }
}
=========================================================================================================================

更多方法,请直接看Arrays 类的源码。。。






猜你喜欢

转载自blog.csdn.net/qq_41694349/article/details/79413786