JavaSE基礎:Arrays工具類

胖先森發表於2018-01-26

Java工具類: Arrays

Arrays類是陣列的操作類,定義在java.util包中,主要功能是實現陣列元素的查詢/陣列內容的充填/排序等功能

1.排序陣列的sort方法

重點:對陣列元素進行排序操作,預設由小到大排序.

該方法的引數不僅可以是基礎資料型別的陣列,也可以是物件引用的陣列。同時還可以指定陣列中需要排序的元素的索引範圍。

當對物件進行排序時,陣列中的所有元素都必須實現 Comparable 介面。(就當你沒有看到,哈哈)

即陣列中的所有元素都必須是可相互比較的(也就是說,對於陣列中的任何 e1 和 e2 元素而言,e1.compareTo(e2) 不得丟擲 ClassCastException)

(1) 數字排序

排序規則:由小到大排序

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest01 {
    public static void main(String[] args) {
        int[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
        Arrays.sort(a);
        for(int i = 0; i < a.length; i ++) {
            System.out.print(a[i] + "\t");
        }
    }
}
複製程式碼

(2) 字串排序

排序規則:先大寫後小寫

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest02 {
    public static void main(String[] args) {
        String[] a = {"a","A","b","B"};
        Arrays.sort(a);
        for(int i = 0; i < a.length; i ++) {
            System.out.print(a[i] + "\t");
        }
    }
}
複製程式碼

(3) 字串嚴格排序

排序規則:嚴格按字母表順序排序,也就是忽略大小寫排序 Case-insensitive sort

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest03 {
    public static void main(String[] args) {
        String[] a = {"a","C","b","D"};
        Arrays.sort(a,String.CASE_INSENSITIVE_ORDER);
        for(int i = 0; i < a.length; i ++) {
            System.out.print(a[i] + "\t");
        }
    }
}
複製程式碼

(4) 反向排序

排序規則:先小寫後大寫

字串反向

package com.shxt.demo03;

import java.util.Arrays;
import java.util.Collections;

public class ArraysTest04 {
    public static void main(String[] args) {
        String[] a = {"a","A","b","B"};
        Arrays.sort(a, Collections.reverseOrder());//Collections 集合類中的工具類
        for(int i = 0; i < a.length; i ++) {
            System.out.print(a[i] + "\t");
        }
    }
}
複製程式碼

數字排序,要使用包裝類

package com.shxt.demo03;

import java.util.Arrays;
import java.util.Collections;

public class ArraysTest05 {
    public static void main(String[] args) {
        //不能使用基本資料型別
        Integer[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
        Arrays.sort(a, Collections.reverseOrder());
        for(int i = 0; i < a.length; i ++) {
            System.out.print(a[i] + "\t");
        }
    }
}
複製程式碼

這個裡面我們使用了Collections工具類,如果想自己完成規則的定義,那麼就需要使用比較器介面Comparable(簡單瞭解即可)

package com.shxt.demo03;

import java.util.Arrays;
import java.util.Comparator;

public class ArraysTest05_1 {
    public static void main(String[] args) {
        //不能使用基本資料型別
        Integer[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
        Arrays.sort(a, new IntegerComparator());
        for(int i = 0; i < a.length; i ++) {
            System.out.print(a[i] + "\t");
        }
    }
}

/**
 * Comparator是一個介面
 * 所以這裡我們自己定義的類IntegerComparator要implents該介面
 * 而不是extends Comparator
 *
 */
class IntegerComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        //如果o1小於o2,我們就返回正值,如果n1大於n2我們就返回負值,
        //這樣顛倒一下,就可以實現反向排序了
        if(o1 < o2) {
            return 1;
        }else if(o1 > o2) {
            return -1;
        }else {
            return 0;
        }
    }
}
複製程式碼

(5) 忽略大小寫反向排序

package com.shxt.demo03;

import java.util.Arrays;
import java.util.Collections;

public class ArraysTest04 {
    public static void main(String[] args) {
        String[] a = {"a","C","b","D"};
        Arrays.sort(a, Collections.reverseOrder());
        Collections.reverse(Arrays.asList(a));//先忽略吧
        for(int i = 0; i < a.length; i ++) {
            System.out.print(a[i] + "\t");
        }
    }
}
複製程式碼

(6) 區間排序-瞭解

Arrays.sort(int[] a, int fromIndex, int toIndex)
複製程式碼

這種形式是對陣列部分排序,也就是對陣列a的下標從fromIndex到toIndex-1的元素排序,注意:下標為toIndex的元素不參與排序!

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest07 {
    public static void main(String[] args) {
        int[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
        Arrays.sort(a, 0, 3);
        for(int i = 0; i < a.length; i ++) {
            System.out.print(a[i] + " ");
        }
    }
}
//執行結果為: 7 8 9 2 3 4 1 0 6 5 
複製程式碼

Java初學者最常見的錯誤思想,就是試圖去寫一些方法來完成陣列的排序功能,

其實,陣列排序功能,在java的api裡面早已實現,我們沒有必要去重複製造輪子。

如果你是應屆生,還是需要學習各種排序的,參考網址:http://geek.csdn.net/news/detail/113928

JDK8強大了排序功能:parallelSort
parallelSort是java8中新出的一種排序API,
這是一種並行排序,Arrays.parallelSort使用了Java7的Fork/Join框架使排序任務可以線上程池中的多個執行緒中進行,
Fork/Join實現了一種任務竊取演算法,一個閒置的執行緒可以竊取其他執行緒的閒置任務進行處理
發現資料量越大,parallelSort的優勢就越明顯。
複製程式碼

2.查詢陣列的binarySearch方法

public static int binarySearch(T[] a, T key)
複製程式碼

使用二分搜尋法來搜尋指定型別陣列,以獲得指定的值。

[重點]必須在進行此呼叫之前對陣列進行排序(通過 sort() 方法)。

如果沒有對陣列進行排序,則結果是不確定的。如果陣列包含多個帶有指定值的元素,則無法保證找到的是哪一個。

返回值說明:

1、如果找到關鍵字,則返回值為關鍵字在陣列中的位置索引,且索引從0開始

2、如果沒有找到關鍵字,返回值為負的插入點值,所謂插入點值就是第一個比關鍵字大的元素在陣列中的位置索引,而且這個位置索引從1開始 (-(插入點)),如果陣列中的所有元素都小於指定的鍵,則為(-a.length-1)。

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest08 {
    public static void main(String[] args) {

        int[] b = new int[]{4, 25, 10, 95, 06, 21};
        System.out.println("原陣列為:");
        for (int dim1 : b) {
            System.out.print("" + dim1 + " ");
        }
        //一定要先排序
        Arrays.sort(b);
        System.out.println("排序後為:");
        for (int x : b) {
            System.out.print(x + " ");
        }
        System.out.println();
        int index = Arrays.binarySearch(b, 2);
        System.out.println("關鍵字2的返回值為:" + index);

        index = Arrays.binarySearch(b, 20);
        System.out.println("關鍵字20的返回值為:" + index);

        index = Arrays.binarySearch(b, 30);
        System.out.println("關鍵字30的返回值為:" + index);

        index = Arrays.binarySearch(b, 100);
        System.out.println("關鍵字100的返回值為:" + index);

        index = Arrays.binarySearch(b, 10);
        System.out.println("關鍵字10的返回值為:" + index);


    }
}
複製程式碼
結果分析如下:
原陣列為:
4 25 10 95 6 21 
排序後為:
4 6 10 21 25 95 
關鍵字2的返回值為:-1 
關鍵字2並沒有在陣列中,而且2比陣列中的任何一個元素都小,所以其插入點的值應為元素4的位置也就是1(沒有找到關鍵字從1開始)

關鍵字20的返回值為:-4
關鍵字20也不在陣列中,陣列中第一個比20大的數是21,所以20的插入點值為4(沒用找到關鍵字從索引從1開始)

關鍵字30的返回值為:-6
關鍵字30也不在陣列中,陣列中第一個比30大的數是95,所以30的插入點值為6(沒用找到關鍵字從索引從1開始)

關鍵字100的返回值為:-7 
關鍵字100也不在陣列中,而且100比陣列中所有的元素都大,此時插入點值為length+17(沒有找到關鍵字索引從1開始)

關鍵字10的返回值為:2
關鍵字10在陣列中,所以返回其在陣列中的索引為2(找到關鍵字索引從0開始)
複製程式碼

3.充填陣列的fill()方法

用指定的值來填充陣列,可以指定需要填充的索引範圍。

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest09 {
    public static void main(String[] args) {

        Integer[] a = new Integer[5];
        Arrays.fill(a, 2);
        System.out.println("當前陣列容器:"+Arrays.toString(a));
        Arrays.fill(a, 5);
        // 數字3覆蓋並填滿了整個Array容器
        System.out.println("當前陣列容器:"+Arrays.toString(a));
        // 填充的開始位
        Integer startIndex = 1;
        // 填充的結束位
        Integer endIndex = 3;
        Arrays.fill(a, startIndex, endIndex, 8);
        System.out.println("當前陣列容器:"+Arrays.toString(a));

    }
}
/*
當前陣列容器:[2, 2, 2, 2, 2]
當前陣列容器:[5, 5, 5, 5, 5]
當前陣列容器:[5, 8, 8, 5, 5]
*/
複製程式碼

4.比較兩個陣列的equals方法

如果兩個指定型別陣列彼此相等,則返回 true。如果兩個陣列包含相同數量的元素,並且兩個陣列中的所有相應元素對都是相等的,則認為這兩個陣列是相等的。換句話說,如果兩個陣列以相同順序包含相同的元素,則兩個陣列是相等的。此外,如果兩個陣列引用都為 null,則認為它們是相等的。

equals方法適用於一維陣列,多維陣列則使用deepEquals(),用法同equals。

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest10 {
    public static void main(String[] args) {
        int[] array1={5,6,9,3,2,4};
        int[] array2={5,6,9,3,2,4};
        int[] array3={6,5,9,3,2,4};
        boolean flag1=Arrays.equals(array1,array2); // true
        boolean flag2=Arrays.equals(array1,array3); // false

        //直接使用equals方法會是什麼結果呢?
        boolean flag3 = array1.equals(array2); //堆記憶體地址不一樣 false  array1==array2


        System.out.println(flag1+" "+flag2+" "+flag3);

    }
}
複製程式碼

5.陣列轉字串toString()方法

返回指定陣列內容的字串表示形式。

字串表示形式由陣列的元素列表組成,括在方括號("[]")中。

相鄰元素用字元 ", "(逗號加空格)分隔。

這些元素通過 String.valueOf(short) 轉換為字串。如果 a 為 null,則返回 "null"。

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest11 {
    public static void main(String[] args) {
        String[] array01 = new String[3];
        System.out.println(array01);
        System.out.println(Arrays.toString(array01));
        
        String[] array02 = {"悟空","八戒","唐僧"};
        System.out.println(array02);
        System.out.println(Arrays.toString(array02));

    }
}
複製程式碼

6.克隆陣列的copyOf方法

如果你想擴大陣列容量又不想改變它的內容的時候可以使用這個方法

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest13 {
    public static void main(String[] args) {
        int[] array1={5,6,9,3,2,4};
        System.out.println("array1的陣列長度:"+array1.length);

        int[] array2 = Arrays.copyOf(array1,array1.length+1);//根據實際情況擴容
        System.out.println("array2的陣列長度:"+array2.length);

        array2[0]=100;

        System.out.println("array1:"+Arrays.toString(array1));
        System.out.println("array2:"+Arrays.toString(array2));
        
    }
}
/**
array1的陣列長度:6
array2的陣列長度:7
array1:[5, 6, 9, 3, 2, 4]
array2:[100, 6, 9, 3, 2, 4, 0]
*/
複製程式碼

array1 和 array2 是兩個不相干的陣列

7.克隆陣列的copyOfRange方法

copyOfRange(int []original,int from,int to)
複製程式碼

original為原始的int型陣列,from為開始角標值,to為終止角標值。(其中包括from角標,不包括to角標。即處於[from,to)狀態)

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest14 {
    public static void main(String[] args) {
        int[] array1={5,6,9,3,2,4};
        int[] array2 = Arrays.copyOfRange(array1,1,5);
        System.out.println("array2的陣列長度:"+array2.length);

        System.out.println("array2:"+Arrays.toString(array2));

    }
}
// 執行結果: array2的陣列長度:4
// array2:[6, 9, 3, 2]
複製程式碼

這個方法比迴圈遍歷複製陣列效率要高。

8.陣列轉列表asList方法

返回一個受指定陣列支援的固定大小的列表。(對返回列表的更改會“直接寫”到陣列。)此方法同Collection.toArray()一起,充當了基於陣列的 API 與基於 collection 的 API 之間的橋樑。返回的列表是可序列化的,並且實現了 RandomAccess。

package com.shxt.demo03;

import java.util.Arrays;
import java.util.List;

public class ArraysTest15 {
    public static void main(String[] args) {
        Integer[] array1={5,6,9,3,2,4};
        List list = Arrays.asList(array1);
        System.out.println("list的長度:"+list.size());
    }
}
// list的長度:6

複製程式碼

避免使用基本資料型別陣列轉換為列表

對上述的程式碼改造一下,改為基本資料型別的陣列

package com.shxt.demo03;

import java.util.Arrays;
import java.util.List;

public class ArraysTest15 {
    public static void main(String[] args) {
        int[] array1={5,6,9,3,2,4};
        List list = Arrays.asList(array1);
        System.out.println("list的長度:"+list.size());
        System.out.println(list);
    }
}
/**
list的長度:1
[[I@4554617c]
*/
複製程式碼

程式的執行結果並沒有像我們預期的那樣是 6 而是逆天的 1,這是什麼情況?

從這個執行結果我們可以充分證明 list 裡面的元素就是 int 陣列。

轉換為列表後不能新增元素

package com.shxt.demo03;

import java.util.Arrays;
import java.util.List;

public class ArraysTest15 {
    public static void main(String[] args) {
        Integer[] array1={5,6,9,3,2,4};
        List list = Arrays.asList(array1);
        list.add(99);//新增元素
    }
}
複製程式碼
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.shxt.demo03.ArraysTest15.main(ArraysTest15.java:10)
複製程式碼

如果想給列表新增資料,需要重新構造列表

package com.shxt.demo03;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArraysTest15 {
    public static void main(String[] args) {
        Integer[] array1={5,6,9,3,2,4};
        List list = Arrays.asList(array1);
        //再次轉換
        List tempList = new ArrayList(list);
        tempList.add(666);
        //可以新增
        System.out.println(tempList);
    }
}
複製程式碼

9.陣列的雜湊碼hashCode

基於指定陣列的內容返回雜湊碼。對於任何兩個滿足 Arrays.equals(a, b) 的同類 型陣列 a 和 b,也可以說 Arrays.hashCode(a) ==Arrays.hashCode(b)。

此方法返回的值與在 List 上呼叫 hashCode 方法獲得的值相同,該 List 包含以相同順序表示 a 陣列元素的例項的序列。如果 a 為 null,則此方法返回 0。

package com.shxt.demo03;

import java.util.Arrays;

public class ArraysTest12 {
    public static void main(String[] args) {
        int[] array1={5,6,9,3,2,4};
        int[] array2={5,6,9,3,2,4};
        int[] array3={6,5,9,3,2,4};

        System.out.println(Arrays.hashCode(array1));
        System.out.println(Arrays.hashCode(array2));
        System.out.println(Arrays.hashCode(array3));

        System.out.println("---------------------");
        //所有的都不一樣
        System.out.println(array1.hashCode());
        System.out.println(array2.hashCode());
        System.out.println(array3.hashCode());

    }
}
/*
1036461630
1036461630
1064167260
---------------------
1163157884
1956725890
356573597
*/
複製程式碼

相關文章