Arrays工具类使用与源码分析(1)

时间:2019-10-21 15:13:59   收藏:0   阅读:65

由于Arrays的方法很多,这一章我们主要从简单的方法进行分析。

1、toString方法


使用方式:

Arrays工具类的toString方法,主要将数组转换为字符串。这在我们打印数组内容的时候非常有用。

   public static void main(String[] args) {
        int[] a = {9, 9, 9, 9, 9};
        int[] b = null;
        int[] c = new int[10];
        int[] d = {};

        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(b));
        System.out.println(Arrays.toString(c));
        System.out.println(Arrays.toString(d));
    }

返回结果如下:

[9, 9, 9, 9, 9]
null
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[]

源码分析

我们只分析一种类型的,比如整型,其余类型的代码大体类似。注意该方法没有对原有数组进行改变,只是新产生了一个包含数组内容的字符串。

   public static String toString(int[] a) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append(‘[‘);
        for (int i = 0; ; i++) {
            b.append(a[i]);
            if (i == iMax)
                return b.append(‘]‘).toString();
            b.append(", ");
        }
    }

2、fill方法


Arrays工具类的fill方法,主要将数组进行填充。比如我们新建了一个数组,之后想对其元素全部初始化为100,这个时候使用for循环进行赋值则显得麻烦,直接使用工具方法便可完成此功能。

使用方式一

   public static void main(String[] args) {
       int[] a = {9, 9, 9, 9, 9};
       Arrays.fill(a, 1);//全部置为1,将原有的9覆盖
        int[] c = new int[10];
       Arrays.fill(c, 3);//全部置为3,类似与赋值
        int[] d = {};
       Arrays.fill(d, 4);//无意义

        System.out.println(Arrays.toString(a));
       System.out.println(Arrays.toString(c));
       System.out.println(Arrays.toString(d));
    }

返回结果如下:

[1, 1, 1, 1, 1]
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
[]

从上面的使用方式来看,这个方法最适合新建一个数组之后,给数组赋值一个初始值,并且这个初始值并不是各个类型默认的值,如0之类的。

源码分析:非常简单,遍历赋值。

    public static void fill(int[] a, int val) {
        for (int i = 0, len = a.length; i < len; i++)
            a[i] = val;
    }

使用方式二

对数组的部分元素填充一个值,从起始位置到结束位置,取头不取尾

    public static void main(String[] args) {
        int[] a = {9, 9, 9, 9, 9};
        Arrays.fill(a, 1, 3, 4);
        //[9, 4, 4, 9, 9]
        System.out.println(Arrays.toString(a));
    }

源码分析:这种部分赋值的方法注意需要记住方法里面的参数的含义即可,通过源码可以清楚看出:

    public static void fill(int[] a, int fromIndex, int toIndex, int val) {
        rangeCheck(a.length, fromIndex, toIndex);
        for (int i = fromIndex; i < toIndex; i++)
            a[i] = val;
    }

下面是参数校验的功能:

   private static void rangeCheck(int arrayLength, int fromIndex, int toIndex) {
        if (fromIndex > toIndex) {
            throw new IllegalArgumentException(
                    "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
        }
        if (fromIndex < 0) {
            throw new ArrayIndexOutOfBoundsException(fromIndex);
        }
        if (toIndex > arrayLength) {
            throw new ArrayIndexOutOfBoundsException(toIndex);
        }
    }

3、copyOf方法


使用方式

copyOf方法的功能是拷贝一个数组。它内部是使用了System.arraycopy方法进行拷贝。首先看下使用方式。

public static void main(String[] args) {
        int[] a = {1, 2};
        System.out.println(Arrays.toString(a)); //[1, 2]

        int[] b = Arrays.copyOf(a, 0);
        System.out.println(Arrays.toString(b)); //[]

        int[] c = Arrays.copyOf(a, 1);
        System.out.println(Arrays.toString(c)); //[1]

        int[] d = Arrays.copyOf(a, 2); //实际可用a.length替代2
        System.out.println(Arrays.toString(d)); //[1, 2]

        int[] e = Arrays.copyOf(a, 3);
        System.out.println(Arrays.toString(e)); //[1, 2, 0]
    }

源码分析:

   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;
    }

该方法需要一个原数组和一个需要生成新数组的长度这两个参数。

注意 Math.min(original.length, newLength) 的含义是,如果传入的长度大于原数组的长度,则使用原数组的长度,否则使用新传入的数组长度。

System.arraycopy介绍

    /*
     * @param      src      原数组.
     * @param      srcPos   从元数据的起始位置开始.
     * @param      dest     目标数组.
     * @param      destPos  目标数组的开始起止位置.
     * @param      length   要拷贝的数组长度.
     * @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);

示例:

    public static void main(String[] args) {
        int[] x = {1, 2, 3, 4, 5, 6, 7};
        int[] y = {11, 12, 13, 14, 15, 16, 17};
        System.arraycopy(x, 1, y, 1, 5);
        System.out.println(Arrays.toString(x));//[1, 2, 3, 4, 5, 6, 7]
        System.out.println(Arrays.toString(y));//[11, 2, 3, 4, 5, 6, 17]
    }

System.arraycopy(x, 1, y, 1, 5); 这句的含义是:

将x数组从第二个位置起拿出5个元素,放置到y数组的第二个位置及以后。

4、copyOfRange方法


copyOfRange方法同样也是拷贝一个数组,只是拷贝的时候需要指定起始位置和结束位置。而copyOf只能传递拷贝的元素的个数,并且是从原数组的第一个元数开始拷贝。

使用方式:

    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5, 6};
        System.out.println(Arrays.toString(a)); //[1, 2, 3, 4, 5, 6]

        int[] b = Arrays.copyOfRange(a, 1, 4);
        System.out.println(Arrays.toString(b)); //[2, 3, 4]

        int[] c = Arrays.copyOfRange(a, 1, 10);
        System.out.println(Arrays.toString(c)); //[2, 3, 4, 5, 6, 0, 0, 0, 0]
    }

源码分析:

    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;
    }

首先判断开始位置和结束位置是否合理,不合理就报错,然后和copyOf源码一样,,使用System.arraycopy方法进行生成新的数组。

关于copyOfRange和copyOf拷贝对象,本节不做介绍,后面会仔细分析。

原文:https://www.cnblogs.com/ye-feng-yu/p/11713283.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!