Collections類(lèi)的常見(jiàn)方法
為了處理Collection類(lèi)的實(shí)例對(duì)象巨柒,java提供了Collections工具類(lèi)來(lái)進(jìn)行操作歼指。該類(lèi)為工具類(lèi)卖丸,內(nèi)部都為static方法糠悯。來(lái)看常見(jiàn)的幾種使用:
Collections.sort()
對(duì)一個(gè)有序的List做排序帮坚。可以自定義排序規(guī)則互艾。
來(lái)看最基本的一個(gè)使用:
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ī)則會(huì)按照默認(rèn)排序進(jìn)行排列试和。再來(lái)看自定義規(guī)則的一個(gè)例子:
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是一個(gè)接口,實(shí)現(xiàn)其內(nèi)部的compare方法即可按照給定規(guī)則排序纫普。
上述排序例子中new Comparator<Integer>() {}是Java的內(nèi)部匿名類(lèi)阅悍,本身接口是不能直接new的,這個(gè)就表示實(shí)際上現(xiàn)在new的是這個(gè)接口的實(shí)現(xiàn)類(lèi)。
Comparator和Comparable的區(qū)別
上述例子中使用了Comparator节视,和前者一樣拳锚,Comparable也是一個(gè)接口,二者表示的不同的地方在于:
- Comparable是排序接口寻行。若一個(gè)類(lèi)實(shí)現(xiàn)了Comparable接口霍掺,就意味著該類(lèi)支持排序
- Comparator是比較接口,我們?nèi)绻枰刂颇硞€(gè)類(lèi)的次序寡痰,而該類(lèi)本身不支持排序(即沒(méi)有實(shí)現(xiàn)Comparable接口)抗楔,那么我們就可以建立一個(gè)“該類(lèi)的比較器”來(lái)進(jìn)行排序,這個(gè)“比較器”只需要實(shí)現(xiàn)Comparator接口即可拦坠。
舉個(gè)例子來(lái)說(shuō)连躏,我們這次創(chuàng)建一個(gè)自定義的可以排序的類(lèi)。
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;
// 這塊不能直接寫(xiě) return this.num - s.num; 因?yàn)闀?huì)存在溢出的情況
// return this.num - s.num;
}
@Override
public String toString() {
return "sortDemo_" + this.num;
}
}
上述例子中贞滨,SortDemo類(lèi)實(shí)現(xiàn)了Comparable接口1入热,重寫(xiě)了compareTo方法,從而使得SortDemo類(lèi)的實(shí)例對(duì)象可以相互比較排序晓铆,直接調(diào)用Collections.sort()
即可按照實(shí)現(xiàn)的compareTo方法進(jìn)行排序勺良,不需要傳入額外的比較邏輯。
對(duì)于上述情況骄噪,不能直接寫(xiě)
return this.num - s.num;
,舉個(gè)例子來(lái)講:byte a = -128; byte b = 1; System.out.println((byte) a - b); // 127 發(fā)生了溢出
再來(lái)看使用Comparator的例子尚困,這次我們的SortDemo類(lèi)并不支持排序,調(diào)用Collections.sort()
傳入一個(gè)實(shí)現(xiàn)Comparator的內(nèi)部匿名類(lèi)來(lá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)部匿名類(lè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)于這個(gè)方法有地方需要注意:
要進(jìn)行查找,要先調(diào)用Collections.sort()進(jìn)行自然順序排序滔韵,不然返回的結(jié)果會(huì)有問(wèn)題
要調(diào)用Collections.sort()逻谦,那要保證List內(nèi)部的類(lèi)型是實(shí)現(xiàn)了Comparable接口的。
對(duì)于Integer這種Java已經(jīng)實(shí)現(xiàn)了Comparable的類(lèi)是可以不做處理的陪蜻,但是我們自定義的類(lèi)要進(jìn)行實(shí)現(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)
這個(gè)方法需要注意的地方是,目的List的長(zhǎng)度要保證不短于要被克隆的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] 隨機(jī)打亂次序
Collections.fill(arr, null);
System.out.println(arr); // [null, null, null, null]
}
}