Arrays工具類使用與源碼分析(1)

  • Arrays工具類主要是方便數組操做的,學習好該類可讓咱們在編程過程當中輕鬆解決數組相關的問題,簡化代碼的開發。
  • Arrays類有一個私有的構造函數,沒有對外提供實例化的方法,所以沒法實例化對象。由於該類是個工具類,所以使用的時候主要使用靜態方法。
  • 因爲數組裏面可包含的對象類型不少,好比int、long、float等等,所以Arrays的靜態方法有不少重載的方法。咱們在學習研究的過程當中只須要針對一種類型研究透便可。

因爲Arrays的方法不少,這一章咱們主要從簡單的方法進行分析。編程

一、toString方法


使用方式:數組

Arrays工具類的toString方法,主要將數組轉換爲字符串。這在咱們打印數組內容的時候很是有用。app

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

返回結果以下:ide

[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(", ");
        }
    }
  • 若是數組爲null,則返回 null 字符串源碼分析

  • 用一個變量 iMax 存儲數組長度減一的值。此值若是爲 -1,表示 數組長度爲0,那麼就返回字符串 [].學習

  • 使用StringBuilder合併字符串,遍歷數組,組裝字符串。而且使用[]括起來。ui

二、fill方法


Arrays工具類的fill方法,主要將數組進行填充。好比咱們新建了一個數組,以後想對其元素所有初始化爲100,這個時候使用for循環進行賦值則顯得麻煩,直接使用工具方法即可完成此功能。 spa

使用方式一

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

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

該方法須要一個原數組和一個須要生成新數組的長度這兩個參數。

  • 首先生成一個新數組,使用指定的長度。
  • 調用System.arraycopy方法進行生成新的數組。

注意 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數組的第二個位置及之後。

四、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拷貝對象,本節不作介紹,後面會仔細分析。

相關文章
相關標籤/搜索