Collections類的常見方法
為了處理Collection類的實例對象,java提供了Collections工具類來進(jìn)行操作。該類為工具類,內(nèi)部都為static方法。來看常見的幾種使用:
Collections.sort()
對一個有序的List做排序??梢宰远x排序規(guī)則。
來看最基本的一個使用:
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add(3);
arr.add(1);
arr.add(4);
arr.add(2);
System.out.println(arr); // [3, 1, 4, 2]
Collections.sort(arr);
System.out.println(arr); // [1, 2, 3, 4]
}
}
如果不指定排序規(guī)則會按照默認(rèn)排序進(jìn)行排列。再來看自定義規(guī)則的一個例子:
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add(3);
arr.add(1);
arr.add(4);
arr.add(2);
System.out.println(arr); // [3, 1, 4, 2]
Collections.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println(arr); // [4, 3, 2, 1]
}
}
Comparator是一個接口,實現(xiàn)其內(nèi)部的compare方法即可按照給定規(guī)則排序。
上述排序例子中new Comparator<Integer>() {}是Java的內(nèi)部匿名類,本身接口是不能直接new的,這個就表示實際上現(xiàn)在new的是這個接口的實現(xiàn)類。
Comparator和Comparable的區(qū)別
上述例子中使用了Comparator,和前者一樣,Comparable也是一個接口,二者表示的不同的地方在于:
- Comparable是排序接口。若一個類實現(xiàn)了Comparable接口,就意味著該類支持排序
- Comparator是比較接口,我們?nèi)绻枰刂颇硞€類的次序,而該類本身不支持排序(即沒有實現(xiàn)Comparable接口),那么我們就可以建立一個“該類的比較器”來進(jìn)行排序,這個“比較器”只需要實現(xiàn)Comparator接口即可。
舉個例子來說,我們這次創(chuàng)建一個自定義的可以排序的類。
package com.DeeJay;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ArrayList<SortDemo> arr = new ArrayList<>();
arr.add(new SortDemo(3));
arr.add(new SortDemo(1));
arr.add(new SortDemo(2));
arr.add(new SortDemo(4));
System.out.println(arr); // [sortDemo_3, sortDemo_1, sortDemo_2, sortDemo_4]
Collections.sort(arr);
System.out.println(arr); // [sortDemo_1, sortDemo_2, sortDemo_3, sortDemo_4]
}
}
class SortDemo implements Comparable {
int num;
public SortDemo(int num) {
this.num = num;
}
@Override
public int compareTo(Object o) {
SortDemo s = (SortDemo) o;
if(this.num < s.num) {
return -1;
}else if(this.num > s.num) {
return 1;
}
return 0;
// 這塊不能直接寫 return this.num - s.num; 因為會存在溢出的情況
// return this.num - s.num;
}
@Override
public String toString() {
return "sortDemo_" + this.num;
}
}
上述例子中,SortDemo類實現(xiàn)了Comparable接口1,重寫了compareTo方法,從而使得SortDemo類的實例對象可以相互比較排序,直接調(diào)用Collections.sort()即可按照實現(xiàn)的compareTo方法進(jìn)行排序,不需要傳入額外的比較邏輯。
對于上述情況,不能直接寫
return this.num - s.num;,舉個例子來講:byte a = -128; byte b = 1; System.out.println((byte) a - b); // 127 發(fā)生了溢出
再來看使用Comparator的例子,這次我們的SortDemo類并不支持排序,調(diào)用Collections.sort()傳入一個實現(xiàn)Comparator的內(nèi)部匿名類來指定排序規(guī)則。
package com.DeeJay;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
ArrayList<SortDemo> arr = new ArrayList<>();
arr.add(new SortDemo(3));
arr.add(new SortDemo(1));
arr.add(new SortDemo(2));
arr.add(new SortDemo(4));
System.out.println(arr); // [sortDemo_3, sortDemo_1, sortDemo_2, sortDemo_4]
Collections.sort(arr, new Comparator<SortDemo>() { // 此處為內(nèi)部匿名類
@Override
public int compare(SortDemo o1, SortDemo o2) {
return o1.num - o2.num;
}
});
System.out.println(arr); // [sortDemo_1, sortDemo_2, sortDemo_3, sortDemo_4]
}
}
class SortDemo{
int num;
public SortDemo(int num) {
this.num = num;
}
@Override
public String toString() {
return "sortDemo_" + this.num;
}
}
Collections.binarySearch
返回指定List和key的index。關(guān)于這個方法有地方需要注意:
要進(jìn)行查找,要先調(diào)用Collections.sort()進(jìn)行自然順序排序,不然返回的結(jié)果會有問題
要調(diào)用Collections.sort(),那要保證List內(nèi)部的類型是實現(xiàn)了Comparable接口的。
對于Integer這種Java已經(jīng)實現(xiàn)了Comparable的類是可以不做處理的,但是我們自定義的類要進(jìn)行實現(xiàn)Comparable。
package com.DeeJay;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add(3);
arr.add(1);
arr.add(2);
arr.add(4);
Collections.sort(arr); // 調(diào)用binarySearch之前要先進(jìn)行sort
System.out.println(Collections.binarySearch(arr, 3));
}
}
Collections.copy(destList, targetList)
這個方法需要注意的地方是,目的List的長度要保證不短于要被克隆的targetList
package com.DeeJay;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add(3);
arr.add(1);
arr.add(2);
arr.add(4);
ArrayList<Integer> arr2 = new ArrayList<>();
arr2.add(null);
arr2.add(null);
arr2.add(null);
arr2.add(null);
Collections.copy(arr2, arr);
System.out.println(arr2); // [3, 1, 2, 4]
}
}
Collections.fill() Collections.reverse() Collections.shuffle()
package com.DeeJay;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add(3);
arr.add(1);
arr.add(2);
arr.add(4);
Collections.sort(arr);
System.out.println(arr);// [1, 2, 3, 4]
Collections.reverse(arr);
System.out.println(arr); // [4, 3, 2, 1]
Collections.shuffle(arr);
System.out.println(arr); // [1, 3, 2, 4] 隨機打亂次序
Collections.fill(arr, null);
System.out.println(arr); // [null, null, null, null]
}
}