集合框架3-Arrays 類

Ethan_Wong發表於2021-09-07

ArraysCollections是分別運算元組和集合的兩個工具類。今天就來對 Arrays 中的內容作個總結。

一、Arrays 類概述

Arrays 類位於 java.util包中。Arrays 繼承 Object

java.lang.Object
 ↳ java.util.Arrays

Arrays 類中的靜態方法可以對陣列進行排序、查詢、搜尋等等操作。

二、Arrays 類中方法

1. Arrays.asList()

方法描述

該方法返回一個 ArrayList , 其返回的 ArrayList 從下面的程式碼可以看出不是我們平常 new 出來的動態可擴充套件的 ArrayList。可以看這篇 ArrayList

@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

/**
     * @serial include
     */
private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{
    private static final long serialVersionUID = -2764017481108945198L;
    private final E[] a;

    ArrayList(E[] array) {
        a = Objects.requireNonNull(array);
    }

    @Override
    public int size() {
        return a.length;
    }

    @Override
    public Object[] toArray() {
        return a.clone();
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        int size = size();
        if (a.length < size)
            return Arrays.copyOf(this.a, size,
                                 (Class<? extends T[]>) a.getClass());
        System.arraycopy(this.a, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

    @Override
    public E get(int index) {
        return a[index];
    }

    @Override
    public E set(int index, E element) {
        E oldValue = a[index];
        a[index] = element;
        return oldValue;
    }

    @Override
    public int indexOf(Object o) {
        E[] a = this.a;
        if (o == null) {
            for (int i = 0; i < a.length; i++)
                if (a[i] == null)
                    return i;
        } else {
            for (int i = 0; i < a.length; i++)
                if (o.equals(a[i]))
                    return i;
        }
        return -1;
    }

    @Override
    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }

    @Override
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator(a, Spliterator.ORDERED);
    }

    @Override
    public void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        for (E e : a) {
            action.accept(e);
        }
    }

    @Override
    public void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        E[] a = this.a;
        for (int i = 0; i < a.length; i++) {
            a[i] = operator.apply(a[i]);
        }
    }

    @Override
    public void sort(Comparator<? super E> c) {
        Arrays.sort(a, c);
    }
}

來個例子

public static void main(String[] args) {
    //建立一個陣列
    int[] a = {1,2,3};
    //new 一個 ArrayList
    ArrayList<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    
    
    System.out.println(list);//[1, 2, 3]
    
    System.out.println(a); //[I@1540e19d
    System.out.println(Arrays.toString(a));//[1, 2, 3]
    
    /*如果將基本資料型別的陣列作為引數傳入,該方法會把整個陣列當成一個元素*/
    System.out.println(Arrays.asList(a));//[[I@1540e19d] 
    System.out.println(Arrays.asList(1,2,3));//[1, 2, 3]
}

2. Arrays.sort(originalArray)

方法描述

對陣列所有元素進行升序排序,沒有返回值。

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
Arrays.sort(a);
System.out.println(Arrays.toString(a));//[1, 2, 3, 4, 5, 6, 7, 8, 9]

3. Arrays.sort(originalArray, fromIndex, endIndex)

方法描述

對陣列特定序列進行升序排序,從 [fromIndex, endIndex]區域的陣列元素進行排序

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
Arrays.sort(a,0,5);
System.out.println(Arrays.toString(a));//[1, 2, 3, 4, 9, 5, 6, 7, 8]

4. Arrays.sort(T[] a, Comparator<super T> c )

方法描述

利用自定義的比較器,來對陣列元素進行排序

來個例子


// Java program to demonstrate working of Comparator
// interface
import java.util.*;
import java.lang.*;
import java.io.*;

// A class to represent a student.
class Student {
    int rollno;
    String name, address;

    // Constructor
    public Student(int rollno, String name,
                   String address)
    {
        this.rollno = rollno;
        this.name = name;
        this.address = address;
    }

    // Used to print student details in main()
    public String toString()
    {
        return this.rollno + " "
            + this.name + " "
            + this.address;
    }
}
//自定義的比較器,對兩個物件的 rollno 屬性進行比較
class Sortbyroll implements Comparator<Student> {
    // Used for sorting in ascending order of
    // roll number
    public int compare(Student a, Student b)
    {
        return a.rollno - b.rollno;
    }
}

// Driver class
class Main {
    public static void main(String[] args)
    {
        Student[] arr = { new Student(1, "bbbb", "london"),
                         new Student(3, "aaaa", "nyc"),
                         new Student(2, "cccc", "jaipur") };

        System.out.println("Unsorted-未排序前");
        for (int i = 0; i < arr.length; i++)
            System.out.println(arr[i]);

        Arrays.sort(arr, new Sortbyroll());

        System.out.println("\nSorted by rollno-排序後");
        for (int i = 0; i < arr.length; i++)
            System.out.println(arr[i]);
    }
}
/** 輸出結果:
*Unsorted-未排序前
*1 bbbb london
*3 aaaa nyc
*2 cccc jaipur
*
*Sorted by rollno-排序後
*1 bbbb london
*2 cccc jaipur
*3 aaaa nyc
*
**/

5. Arrays.sort(T[] a, int fromIndex, int toIndex, Comparator<super T> c)

方法描述

利用自定義的比較器,來對陣列中指定範圍元素進行排序

來個例子

把4中程式碼換成

Arrays.sort(arr, 1, 2, new Sortbyroll());//對第一、二個元素進行比較
/** 輸出結果:
*Unsorted-未排序前
*1 bbbb london
*3 aaaa nyc
*2 cccc jaipur
*
*Sorted by rollno-排序後
*1 bbbb london
*3 aaaa nyc
*2 cccc jaipur
*
**/

6. Arrays.parallelSort(originalArray)

方法描述

對陣列元素進行升序排序,當資料規模較大時,效能更好(並行排序)。

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
Arrays.parallelSort(a);
System.out.println(Arrays.toString(a));//[1, 2, 3, 4, 9, 5, 6, 7, 8]

7.Arrays.fill(originalArray, fillValue)Arrays.fill(originalArray, intfromIndex, int toIndex, fillValue)

方法描述

用 fillValue 值來填充陣列。前一個函式填充所有,後面的函式填充指定範圍。

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
Arrays.fill(a,1);//[1, 1, 1, 1, 1, 1, 1, 1, 1]
Arrays.fill(a,1,3,1);//[1, 1, 1, 9, 4, 5, 6, 7, 8]

8.Arrays.equals(array1, array2)Arrays.deepEquals(array1, array2)

方法描述

判斷兩個陣列是否相等, 返回布林值

equals()主要針對基本資料和Object 一維陣列,其比較規則如下:

if (a==a2)
    return true;
if (a==null || a2==null)
    return false;

int length = a.length;
if (a2.length != length)
    return false;

for (int i=0; i<length; i++) {
    Object o1 = a[i];
    Object o2 = a2[i];
    if (!(o1==null ? o2==null : o1.equals(o2)))
        return false;
}

return true;

deepEquals()主要是多維陣列的比較,其比較規則為:

if (a1 == a2)
    return true;
if (a1 == null || a2==null)
    return false;
int length = a1.length;
if (a2.length != length)
    return false;

for (int i = 0; i < length; i++) {
    Object e1 = a1[i];
    Object e2 = a2[i];

    if (e1 == e2)
        continue;
    if (e1 == null)
        return false;

    // Figure out whether the two elements are equal
    boolean eq = deepEquals0(e1, e2);

    if (!eq)
        return false;
}

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
int[] b = {1,2};
int[][] c = {{1,2},{1,3}};
int[][] d = {{1,2},{1,3}};
Arrays.equals(a,b);//false
Arrays.equals(c,d);//true

9.Arrays.hashCode(originalArray)Arrays.deepHashCode(originalArray)

方法描述

返回該陣列的雜湊值

前面一個函式是返回一維陣列,後面是多維陣列

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
int[][] c = {{1,2},{1,3}};
System.out.println(Arrays.hashCode(a));//887857437
System.out.println(Arrays.deepHashCode(c));//31776

10.Arrays.binarySearch(originalArray, key)Arrays.binarySearch(originalArray,fromIndex,toIndex,key,Comparator)

方法描述

方法一:在陣列中對某值進行二分查詢(注意要先對陣列排序!),如果存在返回其下標,否則返回 -(陣列極值下標 +1)。

方法二:方法中的引數限定陣列的範圍,Comparator 是自定義的比較器

來個例子

int[] a = {1,2,3,4,5,9,6,7,8};
Arrays.sort(a);
System.out.println(Arrays.binarySearch(a,1));//0
System.out.println(Arrays.binarySearch(a,0));//-1
System.out.println(Arrays.binarySearch(a,10));//-10

11.Arrays.copyOf(originalArray, newLength)Arrays.copyOfRange(originalArray,fromIndex,endIndex)

方法描述

方法一:拷貝陣列,newLength 是拷貝的長度,如果超過原陣列的長度,則用 null 進行填充。並返回一個新陣列。

方法二:拷貝陣列,fromIndex 和 endIndex 是陣列的範圍下標。並返回一個新陣列。

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
System.out.println(Arrays.toString(Arrays.copyOf(a,3)));//[1,2,3]
System.out.println(Arrays.toString(Arrays.copyOfRange(a,0,3)));//[1,2,3]

13.Arrays.toString(originalArray)Arrays.deepToString(originalArray)

方法描述

返回陣列元素的字串形式,方法一是一維陣列,方法二是多維陣列。

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
System.out.println(Arrays.toString(a));//[1,2,3,9,4,5,6,7,8]
int[][] c = {{1,2},{3}};
System.out.println(Arrays.deepToString(c));//[[1, 2], [3]]

14.Arrays.setAll(originalArray,functionalGenerator)Arrays.parallelSetAll(originalArray, functionalGenerator)

方法描述

方法一:將陣列中的所有元素,序列的使用方法提供的生成器函式來計算每個元素(一元操作)

方法二:將陣列中的所有元素,序列的使用方法提供的生成器來計算每個元素(一元操作)適用於大規模資料

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
Arrays.setAll(a, i -> a[i] * 2);
System.out.println(Arrays.toString(a));//[2,4,6,18,8,10,12,14,16]

Arrays.parallelSetAll(a, i  -> a[i] * 2);
System.out.println(Arrays.toString(a));//[2,4,6,18,8,10,12,14,16]

15. Arrays.parallelPrefix(originalArray, BinaryOperator op) Arrays.parallelPrefix(originalArray, int fromIndex, int toIndex, BinaryOperator op)

方法描述

方法一:將陣列中所有元素,並行使用生成器函式來計算每個元素(二元操作)

方法二:將陣列中部分序列元素,並行使用生成器函式來計算每個元素(二元操作)

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
Arrays.parallelPrefix(a, (x,y) -> x*y);//依次累乘
System.out.println(Arrays.toString(a));//[1, 2, 6, 54, 216, 1080, 6480, 45360, 362880]

Arrays.parallelPrefix(a, 0, 3, (x,y) -> x*y);//依次累乘
System.out.println(Arrays.toString(a));//[1, 2, 6, 9, 4, 5, 6, 7, 8]

16.Arrays.spliterator(originalArray)Arrays.spliterator(originalArray,fromIndex,endIndex)

方法描述

返回陣列的分片迭代器,用於並行的遍歷陣列

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
Spliterator<Integer> s = Arrays.spliterator(a);
s.forEachRemaining(System.out::println);
/**
*
*1
*2
*3
*9
*4
*5
*6
*7
*8
**/

17.Arrays.stream(originalArray)

方法描述

返回陣列的流,可以對陣列使用 Stream 相關的方法。

來個例子

int[] a = {1,2,3,9,4,5,6,7,8};
List<Integer> list = Arrays.stream(a).collect(toList());
System.out.println(list);//[1,2,3,9,4,5,6,7,]

三、參考資料

Arrays class in Java

Java Collections - Arrays.spliterator() Example

Arrays 類常用方法解析

相關文章