Arrays用法總結

數組轉字符串

int[] array = new int[]{1, 2, 3};
out.println(Arrays.toString(array)); //[1, 2, 3]

如果是一維數組,toString方法可以很好的適用。但遇到多維數組時,需要使用deepToString把數組完全轉成字符串。

int[][] deepArray = new int[][]{{1, 3},{2, 4}};
out.println(Arrays.toString(deepArray)); //[[I@1540e19d, [I@677327b6]
out.println(Arrays.deepToString(deepArray)); //[[1, 3], [2, 4]]

填充數組

array = new int[5];
Arrays.fill(array, 2);
out.println(Arrays.toString(array)); //[2, 2, 2, 2, 2]

array = new int[5];
Arrays.fill(array, 1, 4, 2); //部分填充
out.println(Arrays.toString(array));//[0, 2, 2, 2, 0]

數組元素排序

array = new int[]{3, 10, 4, 0, 2};
Arrays.sort(array);
out.println(Arrays.toString(array)); //[0, 2, 3, 4, 10]

array = new int[]{3, 10, 4, 0, 2};
Arrays.parallelSort(array); //和sort相比是這個是並行的
out.println(Arrays.toString(array)); //[0, 2, 3, 4, 10]

array = new int[]{3, 10, 4, 0, 2};
Arrays.sort(array, 0, 4); //部分排序
out.println(Arrays.toString(array)); //[0, 3, 4, 10, 2]

數組的比較

array = new int[]{1, 2, 3};
int[] array2 = new int[]{1, 2, 3};
out.println(Arrays.equals(array, array2)); //true

和toString方法一樣,equals方法遇到多維數組時也會出現問題。

int[][] deepArray1 = new int[][]{{1, 3},{2, 4}};
int[][] deepArray2 = new int[][]{{1, 3},{2, 4}};
out.println(Arrays.equals(deepArray1, deepArray2)); //false
out.println(Arrays.deepEquals(deepArray1, deepArray2)); //true

deepEquals用於判定兩個指定數組彼此是否深層相等,此方法適用於任意深度的嵌套數組。

equals用於判定兩個數組是否相等,如果兩個數組以相同順序包含相同元素,則返回true。

如果兩個數組使用equals返回true,則使用deepEquals必定也返回true,也就是說在比較的兩個數組均爲一維數組的前提下,equals和deepEquals的比較結果沒有差別。

數組複製

array = new int[]{3, 10, 4, 0, 2};
int[] arrayCopy = Arrays.copyOf(array, 3);
out.println(Arrays.toString(arrayCopy)); //[3, 10, 4]

arrayCopy = Arrays.copyOf(array, 7);
out.println(Arrays.toString(arrayCopy)); //[3, 10, 4, 0, 2, 0, 0], 多出的長度補0

arrayCopy = Arrays.copyOfRange(array, 1, 4);
out.println(Arrays.toString(arrayCopy)); //[10, 4, 0]

二分查找返回下標

array = new int[]{0, 3, 4, 10, 20};
out.println(Arrays.binarySearch(array, 10)); //3, array必須是排序的,否則得到的是錯誤的結果
out.println(Arrays.binarySearch(array, 6)); //-4, 找不到的值,從-1開始,6如果存在下標是3, 所以返回-4
out.println(Arrays.binarySearch(array, 2, 5, 10)); //3, 返回的還是全局的下標值。

數組轉List

int array = new int[]{3, 10, 4, 0, 2};
out.println(Arrays.asList(array).contains(3)); //false

Integer arr[] = new Integer[]{3, 10, 4, 0, 2};
out.println(Arrays.asList(arr).contains(3)); //true

這裏是比較有意思的地方,實際上拆開來看是這樣的

int array = new int[]{3, 10, 4, 0, 2};
List<int[]> ints = Arrays.asList(array);
Integer arr[] = new Integer[]{3, 10, 4, 0, 2};
List<Integer> integers = Arrays.asList(arr);

現在就知道區別了,原始數據類型int的數組調用asList之後得到的List只有一個元素,這個元素就是元素類型的數組。而封裝類Integer數組調用asList是把數組中每個元素加到了List中。

對數組元素採用指定的方法計算

array = new int[]{3, 10, 4, 0, 2};
Arrays.parallelPrefix(array, (x,y)->(x+y)); //[3, 13, 17, 17, 19]
out.println(Arrays.toString(array));

array = new int[]{3, 10, 4, 0, 2};
Arrays.parallelSetAll(array, (x)->(x*x)); //[0, 1, 4, 9, 16]
out.println(Arrays.toString(array));

Arrays.setAll(array, (x)->(x%3));
out.println(Arrays.toString(array)); //[0, 1, 2, 0, 1], 與parallelSetAll相比只是不併行

對其他對象數組進行排序

一個對象數組,排序算法需要重複比較數組中的元素。不同的類比較元素的規則是不同的,但是排序算法只應該調用類提供的比較方法,只要所有的類就比較的時候提供的方法達成一致,那麼排序算法就能開始工作。這個在排序時對象之間進行比較方法就可以是一個接口,所有需要比較的對象繼承這個接口並且實現比較的方法,就可以對這些對象進行排序。
如果一個類想啓用對象排序,那麼就應該實現Comparable接口。

public class Test{
    public static void main(String[] args){
        Employee[] employees = new Employee[3];
        employees[0] = new Employee(20);
        employees[1] = new Employee(10);
        employees[2] = new Employee(30);
        Arrays.sort(employees);
        for(Employee e : employees){
            System.out.println(e); //Employee{id=10} Employee{id=20} Employee{id=30}
        }

    }
    static class Employee implements Comparable<Employee>{
        private int id;
        public Employee(int id){this.id = id;}
@Override
        public int compareTo(Employee o) {
            return this.id - o.id;
        }
        @Override
        public String toString() {
            return "Employee{" + "id=" + id + '}';
        }
    }
}

自定義排序規則

String[] names = {"tom", "alice", "fred"};
Arrays.sort(names);
out.println(Arrays.toString(names));

假如想根據字符串的長度而不是根據字典順序對字符串排序,但是String類我們是無法修改的。上面的代碼對String數組進行排序,只能按照字典順序對String數組進行排序。
Arrays.sort方法和Collections.sort方法都提供了一個可以接收Comparator實例作爲第二個參數的版本。
要按照長度比較字符串,定義一個實現Comparator<String>的類。

public class LengthComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
        return o1.length() - o2.length();
    }
    public static void main(String[] args){
        String[] names = {"tom", "alice", "fred"};
        Arrays.sort(names, new LengthComparator());
        out.println(Arrays.toString(names));
    }
}

像Comparator、Runable等這=一些接口有一個特點就是隻有一個抽象方法(其他的都是static或者default的方法),比如繼承Comparator接口只需要重寫compare方法,繼承Runnable接口只需要重寫run方法,這種類型的接口被稱爲函數式接口,可以被lambda表達式所代替。
比如上面根據字符串的長度進行排序的代碼,Arrays.sort的第二個參數是需要實現了Comparator接口的實例,用lambda表達是就可以寫成這樣:

String[] names = {"tom", "alice", "fred"};
Comparator<String> comp = (first, second) -> first.length() - second.length();
Arrays.sort(names, comp);

或者更加簡單點

String[] names = {"tom", "alice", "fred"};
Arrays.sort(names, (first, second) -> first.length() - second.length());

Arrays.sort方法的第二個參數變量接受一個實現了Comparator接口的類的實例,調用該對象的compare方法會執行lambda表達式中的代碼,所以這也就是爲什麼接口只有一個抽象方法的時候可以用lambda表達式代替。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章