一、Comparable和Comparator的詳解
Comparable & Comparator 都是用來實現集合中元素的比較、排序的,只是 Comparable 是在集合內部定義的方法實現的排序,Comparator 是在集合外部實現的排序,所以,如想實現排序,就需要在集合外定義 Comparator 接口的方法或在集合內實現 Comparable 接口的方法。
(1)Comparable(內比較器)
Comparable可以認為是一個內比較器,實現了Comparable接口的類有一個特點,就是這些類是可以和自己比較的,至於具體和另一個實現了Comparable接口的類如何比較,則依賴compareTo方法的實現,compareTo方法也被稱為自然比較方法。如果開發者add進入一個Collection的對象想要Collections的sort方法幫你自動進行排序的話,那么這個對象必須實現Comparable接口。compareTo方法的返回值是int,有三種情況:
1、比較者大於被比較者(也就是compareTo方法里面的對象),那么返回正整數
2、比較者等於被比較者,那么返回0
3、比較者小於被比較者,那么返回負整數
public class Domain implements Comparable<Domain>
{
private String str;
public Domain(String str)
{
this.str = str;
}
public int compareTo(Domain domain)
{
if (this.str.compareTo(domain.str) > 0)
return 1;
else if (this.str.compareTo(domain.str) == 0)
return 0;
else
return -1;
}
public String getStr()
{
return str;
}
}
public static void main(String[] args)
{
Domain d1 = new Domain("c");
Domain d2 = new Domain("c");
Domain d3 = new Domain("b");
Domain d4 = new Domain("d");
System.out.println(d1.compareTo(d2));
System.out.println(d1.compareTo(d3));
System.out.println(d1.compareTo(d4));
}
(2)Comparator(外比較器)
Comparator可以認為是是一個外比較器,個人認為有兩種情況可以使用實現Comparator接口的方式:
1、一個對象不支持自己和自己比較(沒有實現Comparable接口),但是又想對兩個對象進行比較
2、一個對象實現了Comparable接口,但是開發者認為compareTo方法中的比較方式並不是自己想要的那種比較方式
Comparator接口里面有一個compare方法,方法有兩個參數T o1和T o2,是泛型的表示方式,分別表示待比較的兩個對象,方法返回值和Comparable接口一樣是int,有三種情況:
1、o1大於o2,返回正整數
2、o1等於o2,返回0
3、o1小於o3,返回負整數
public class DomainComparator implements Comparator<Domain>
{
public int compare(Domain domain1, Domain domain2)
{
if (domain1.getStr().compareTo(domain2.getStr()) > 0)
return 1;
else if (domain1.getStr().compareTo(domain2.getStr()) == 0)
return 0;
else
return -1;
}
}
public static void main(String[] args)
{
Domain d1 = new Domain("c");
Domain d2 = new Domain("c");
Domain d3 = new Domain("b");
Domain d4 = new Domain("d");
DomainComparator dc = new DomainComparator();
System.out.println(dc.compare(d1, d2));
System.out.println(dc.compare(d1, d3));
System.out.println(dc.compare(d1, d4));
}
(3)總結
總結一下,兩種比較器Comparable和Comparator,后者相比前者有如下優點:
1、如果實現類沒有實現Comparable接口,又想對兩個類進行比較(或者實現類實現了Comparable接口,但是對compareTo方法內的比較算法不滿意),那么可以實現Comparator接口,自定義一個比較器,寫比較算法
2、實現Comparable接口的方式比實現Comparator接口的耦合性 要強一些,如果要修改比較算法,要修改Comparable接口的實現類,而實現Comparator的類是在外部進行比較的,不需要對實現類有任何修 改。從這個角度說,其實有些不太好,尤其在我們將實現類的.class文件打成一個.jar文件提供給開發者使用的時候。實際上實現Comparator 接口的方式后面會寫到就是一種典型的策略模式。
二、Arrays類詳解
java.util.Arrays類是JDK提供的一個工具類,用來處理數組的各種方法,而且每個方法基本上都是靜態方法,能直接通過類名Arrays調用
常用方法
asList
作用是返回由指定數組支持的固定大小列表
注意:這個方法返回的ArrayList 不是我們常用的集合類 java.util.ArrayList。這里的 ArrayList 是 Arrays 的一個內部類 java.util.Arrays.ArrayList。(返回的 ArrayList 數組是一個定長列表,我們只能對其進行查看或者修改,但是不能進行添加或者刪除操作)
List<String> listStr = new ArrayList<>(Arrays.asList(str));
sort
該方法是用於數組排序,在Arrays類中有該方法的一系列重載方法,能對7種基本數據類型,包括 byte,char,double,float,int,long,short 等都能進行排序,還有 Object 類型(實現了Comparable接口),以及比較器 Comparator 。
binarySearch
用二分法查找數組中的某個元素,該方法和sort方法一樣,適用於各種基本數據類型以及對象
注意:二分法是對以及有序的數組進行查找(比如先用Arrays.sort()進行排序,然后調用此方法進行查找)。找到元素返回下標,沒有則返回 -1
copyOf
拷貝數組元素。底層采用 System.arraycopy() 實現,這是一個native方法。
equals和deepEquals
equals 用來比較兩個數組中對應位置的每個元素是否相等。
deepEquals也是用來判斷比較兩個數組的元素是否相等,不過 deepEquals 能夠進行比較多維數組,而且是任意層次的嵌套數組。
String[][] name1 = {{ "G","a","o" },{ "H","u","a","n"},{ "j","i","e"}};
String[][] name2 = {{ "G","a","o" },{ "H","u","a","n"},{ "j","i","e"}};
System.out.println(Arrays.equals(name1,name2));// false
System.out.println(Arrays.deepEquals(name1,name2));// true
fill
該系列方法用於給數組賦值,並能指定某個范圍賦值。
toString和deepToString
toString 用來打印一維數組的元素,而 deepToString 用來打印多層次嵌套的數組元素。
三、Collections類詳解
Collections是集合類的一個工具類,其中提供了一系列靜態方法,用於對集合中元素進行排序、搜索以及線程安全等各種操作
排序方法
Collections提供了以下方法對List進行排序
void reverse(List list):反轉
void shuffle(List list),隨機排序
void sort(List list),按自然排序的升序排序
void sort(List list, Comparator c);定制排序,由Comparator控制排序邏輯
void swap(List list, int i , int j),交換兩個索引位置的元素
void rotate(List list, int distance),旋轉。當distance為正數時,將list后distance個元素整體移到前面。當distance為負數時,將 list的前distance個元素整體移到后面。
sort
看一下sort(List list)源碼
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
list接口里的sort方法
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
查找,替換操作
int binarySearch(List list, Object key), 對List進行二分查找,返回索引,注意List必須是有序的
int max(Collection coll),根據元素的自然順序,返回最大的元素。 類比int min(Collection coll)
int max(Collection coll, Comparator c),根據定制排序,返回最大元素,排序規則由Comparatator類控制。類比int min(Collection coll, Comparator c)
void fill(List list, Object obj),用元素obj填充list中所有元素
int frequency(Collection c, Object o),統計元素出現次數
int indexOfSubList(List list, List target), 統計targe在list中第一次出現的索引,找不到則返回-1,類比int lastIndexOfSubList(List source, list target).
boolean replaceAll(List list, Object oldVal, Object newVal), 用新元素替換舊元素。
同步控制
Collections中幾乎對每個集合都定義了同步控制方法,例如 SynchronizedList(), SynchronizedSet(),SynchronizedMap()等方法,來將集合包裝成線程安全的集合。