一.數(shù)據(jù)結(jié)構(gòu)
(一)常見的數(shù)據(jù)結(jié)構(gòu)
數(shù)據(jù)存儲的常用結(jié)構(gòu)有:棧、隊列舷蒲、數(shù)組矢炼、鏈表和紅黑樹。
(二)常見數(shù)據(jù)結(jié)構(gòu)簡介
1.棧
棧(stack):又稱堆棧阿纤,它是的線性表句灌,其限制是僅允許在表的一端進行插入和刪除操作,不允許在其他任何位置進行添加欠拾、查找胰锌、刪除等操作。
(1) 元素的存取的特點:
-
(即藐窄,存進去的元素资昧,要在后它后面的元素依次取出后,才能取出該元素)荆忍。
- 棧的入口格带、出口的都是棧的頂端位置。
(2) 跟棧有關(guān)的兩個名詞:
- 壓棧:就是存元素刹枉。即叽唱,把元素存儲到棧的頂端位置,棧中已有元素依次向棧底方向移動一個位置微宝。
- 彈棧:就是取元素棺亭。即,把棧的頂端位置元素取出蟋软,棧中已有元素依次向棧頂方向移動一個位置镶摘。
2.隊列
隊列(queue):簡稱隊,它同堆棧一樣岳守,也是一種的線性表凄敢,其限制是僅允許在表的一端進行插入,而在表的另一端進行刪除湿痢。
(1) 元素的存取的特點:
-
(即涝缝,存進去的元素,要在后它前面的元素依次取出后蒙袍,才能取出該元素)俊卤。
- 隊列的入口、出口各占一側(cè)害幅。例如消恍,下圖中的左側(cè)為入口,右側(cè)為出口以现。
3.數(shù)組
數(shù)組(Array):是有序的元素序列狠怨,數(shù)組是在內(nèi)存中開辟一段連續(xù)的空間约啊,并在此空間存放元素。
(1) 元素的存取的特點:
- 查找元素快:通過索引佣赖,可以快速訪問指定位置的元素
- 增刪元素慢
指定索引位置增加元素:需要創(chuàng)建一個新數(shù)組恰矩,將指定新元素存儲在指定索引位置,再把原數(shù)組元素根據(jù)索引憎蛤,復(fù)制到新數(shù)組對應(yīng)索引的位置外傅。
數(shù)組添加.png
指定索引位置刪除元素:需要創(chuàng)建一個新數(shù)組,把原數(shù)組元素根據(jù)索引俩檬,復(fù)制到新數(shù)組對應(yīng)索引的位置萎胰,原數(shù)組中指定索引位置元素不復(fù)制到新數(shù)組中。
4.鏈表
鏈表(linked list):由一系列結(jié)點node
(鏈表中每一個元素稱為結(jié)點)組成棚辽,結(jié)點可以在運行時動態(tài)生成技竟。每個結(jié)點包括兩個部分:一個是存儲數(shù)據(jù)元素的,另一個是存儲下一個結(jié)點地址的
屈藐。
(1) 元素的存取的特點:
多個結(jié)點之間榔组,通過
進行連接。
查找元素慢:想查找某個元素联逻,需要通過連接的節(jié)點搓扯,依次向后查找指定元素
-
增刪元素快:
- 增加元素:只需要修改連接下個元素的地址即可。
- 刪除元素:只需要修改連接下個元素的地址即可遣妥。
5.紅黑樹
(1) 二叉樹
二叉樹(binary tree):是每個結(jié)點不超過2的有序樹(tree) 擅编。
二叉樹是每個節(jié)點最多有兩個子樹的樹結(jié)構(gòu)。頂上的叫根結(jié)點箫踩,兩邊被稱作“左子樹”和“右子樹”。
(2) 紅黑樹:
我們要說的是二叉樹的一種紅黑樹谭贪,紅黑樹本身就是一顆境钟,將節(jié)點插入后,該樹仍然是一顆二叉查找樹俭识。也就意味著慨削,樹的鍵值仍然是
的。
(3) 紅黑樹的約束:
- 節(jié)點可以是紅色的或者黑色的
- 根節(jié)點是黑色的
- 葉子節(jié)點(特指空節(jié)點)是黑色的
- 每個紅色節(jié)點的子節(jié)點都是黑色的
- 任何一個節(jié)點到其每一個葉子節(jié)點的所有路徑上黑色節(jié)點數(shù)相同
(4) 紅黑樹的特點:
速度特別快,趨近平衡樹,查找葉子元素最少和最多次數(shù)不多于二倍
二.List接口
Collection
集合中有幾個常用的子類:java.util.List
集合套媚、java.util.Set
集合缚态。
(一)List接口介紹
java.util.List
接口繼承自Collection
接口,是單列集合的一個重要分支堤瘤,習慣性地會將實現(xiàn)了List
接口的對象稱為List
集合玫芦。在List
集合中允許出現(xiàn)重復(fù)的元素,所有的元素是以一種線性方式進行存儲的本辐,在程序中可以通過索引來訪問集合中的指定元素桥帆。另外医增,List
集合還有一個特點就是元素有序,即元素的存入順序和取出順序一致老虫。
(二)List接口特點
- 它是一個元素存取有序的集合,存儲元素和取出元素的順序是一致的叶骨。
- 它是一個帶有索引的集合,通過索引就可以精確的操作集合中的元素祈匙。
-
List
集合中允許存儲重復(fù)的元素忽刽。
(三)List接口中常用方法
List
作為Collection
集合的子接口,不但繼承了Collection
接口中的全部方法夺欲,而且還增加了一些根據(jù)元素索引來操作集合的特有方法:
-
public void add(int index, E element)
: 將指定的元素缔恳,添加到該集合中的指定位置上。 -
public E get(int index)
:返回集合中指定位置的元素洁闰。 -
public E remove(int index)
: 移除列表中指定位置的元素, 返回的是被移除的元素歉甚。 -
public E set(int index, E element)
:用指定元素替換集合中指定位置的元素,返回值的更新前的元素。
代碼:
public class ListTest {
public static void main(String[] args) {
/*
public void add(int index, E element): 將指定的元素扑眉,添加到該集合中的指定位置上纸泄。
public E get(int index):返回集合中指定位置的元素。
public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素腰素。
public E set(int index, E element):用指定元素替換集合中指定位置的元素,返回值的更新前的元素聘裁。
*/
// 創(chuàng)建一個List集合對象,多態(tài)
List<String> list = new ArrayList<>();
list.add("張三");
list.add("李四");
list.add("王五");
list.add("趙六");
System.out.println("list集合中的元素為: " + list);
// 在李四和王五之間插入一個張哈哈
list.add(2, "張哈哈");
System.out.println("在李四和王五之間插入一個張哈哈后list集合中的元素為: " + list);
// 獲取list集合第1號索引位置的元素
System.out.println("list集合中1號索引位置的元素為: " + list.get(1));
// 移除list集合第0號索引位置的元素
String str = list.remove(0);
System.out.println("移除list集合第0號索引位置的元素后list集合中的元素為: " + list);
System.out.println("被移除的元素為: " + str);
// 設(shè)置list集合第3號索引位置的元素為三毛
list.set(3, "三毛");
System.out.println("設(shè)置list集合第3號索引位置的元素為三毛后list集合中的元素為: " + list);
// 使用for循環(huán)遍歷list集合
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println("\n==========================");
// 使用迭代器遍歷list集合
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
System.out.println("\n==========================");
// 使用增強for循環(huán)遍歷list集合
for (String i : list) {
System.out.print(i + " ");
}
}
}
運行結(jié)果:
注意:操作索引的時候,一定要防止索引越界異常
IndexOutOfBoundsException
:索引越界異常,集合會報ArrayIndexOutOfBoundsException
:數(shù)組索引越界異常StringIndexOutOfBoundsException
:字符串索引越界異常
(四)List集合的子類
1.ArrayList集合
java.util.ArrayList
集合數(shù)據(jù)存儲的結(jié)構(gòu)是數(shù)組結(jié)構(gòu)。元素弓千,
衡便,由于日常開發(fā)中使用最多的功能為查詢數(shù)據(jù)、遍歷數(shù)據(jù)洋访,所以
ArrayList
是最常用的集合镣陕。
2.LinkedList集合
java.util.LinkedList
集合數(shù)據(jù)存儲的結(jié)構(gòu)是鏈表結(jié)構(gòu)。方便元素添加姻政、刪除的集合呆抑,元素,
汁展。
LinkedList是一個雙向鏈表
(1) 常用方法:
實際開發(fā)中對一個集合元素的添加與刪除經(jīng)常涉及到首尾操作鹊碍,而
LinkedList
提供了大量首尾操作的方法。
-
public void addFirst(E e)
:將指定元素插入此列表的開頭食绿。 -
public void addLast(E e)
:將指定元素添加到此列表的結(jié)尾侈咕。 -
public E getFirst()
:返回此列表的第一個元素。 -
public E getLast()
:返回此列表的最后一個元素器紧。 -
public E removeFirst()
:移除并返回此列表的第一個元素耀销。 -
public E removeLast()
:移除并返回此列表的最后一個元素。 -
public E pop()
:從此列表所表示的堆棧處彈出一個元素品洛。 -
public void push(E e)
:將元素推入此列表所表示的堆棧树姨。
代碼:
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("a");
linkedList.add("b");
linkedList.add("c");
linkedList.add("d");
method1(linkedList);
method2(linkedList);
}
/*
public void addFirst(E e):將指定元素插入此列表的開頭摩桶。
public void addLast(E e):將指定元素添加到此列表的結(jié)尾。
public E getFirst():返回此列表的第一個元素帽揪。
public E getLast():返回此列表的最后一個元素硝清。
*/
private static void method1(LinkedList<String> list) {
System.out.println("初始列表中元素為: " + list);
// 將www插入此列表的開頭。
list.addFirst("www");
System.out.println("列表中元素為: " + list);
// 將com插入此列表的結(jié)尾转晰。(相當于add()方法)
list.addLast("com");
System.out.println("列表中元素為: " + list);
// 返回此列表的第一個元素
System.out.println("此列表第一個元素是: " + list.getFirst());
// 返回此列表的最后一個元素
System.out.println("此列表最后一個元素元素是: " + list.getLast());
}
/*
public E removeFirst():移除并返回此列表的第一個元素芦拿。
public E removeLast():移除并返回此列表的最后一個元素。
public E pop():從此列表所表示的堆棧處彈出一個元素查邢。
public void push(E e):將元素推入此列表所表示的堆棧蔗崎。
*/
private static void method2(LinkedList<String> list) {
System.out.println("初始列表中元素為: " + list);
// 移除并返回此列表的第一個元素
String elementFirst = list.removeFirst();
System.out.println("列表中元素為: " + list);
System.out.println("移除的元素為: " + elementFirst);
// 移除并返回此列表的最后一個元素
String elementLast =list.removeLast();
System.out.println("列表中元素為: " + list);
System.out.println("移除的元素為: " + elementLast);
// 從此列表所表示的堆棧處彈出一個元素(相當于removeFirst()方法)
String elementPop=list.pop();
System.out.println("列表中元素為: " + list);
System.out.println("彈出的元素為: " + elementPop);
// 將www推入此列表所表示的堆棧(相當于addFirst()方法)
list.push("張三");
System.out.println("列表中元素為: " + list);
}
}
運行結(jié)果:
(2) LinkedList特點
- 底層是一個鏈表結(jié)構(gòu):查詢慢,增刪快
- 里邊包含了大量操作首尾元素的方法
在開發(fā)時,
LinkedList
集合也可以作為堆棧扰藕,隊列的結(jié)構(gòu)使用缓苛。
3.Vector向量
Vector
類可以實現(xiàn)可增長的對象數(shù)組。與數(shù)組一樣邓深,它包含可以使用整數(shù)索引進行訪問的組件未桥。但是,Vector
的大小可以根據(jù)需要增大或縮小芥备,以適應(yīng)創(chuàng)建Vector
后進行添加或移除項的操作冬耿。
(1) 常用方法:
-
public void addElement(E obj)
:將指定的組件添加到此向量的末尾,將其大小增加 1萌壳。 -
public int capacity()
:返回此向量的當前容量亦镶。 -
Enumeration<E> elements()
:返回此向量的組件的枚舉。
代碼:
public class VectorTest {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
// 向vector向量中添加元素
vector.addElement("a");
vector.addElement("b");
vector.addElement("c");
System.out.println(vector);
System.out.println("vector向量的長度為: " + vector.size());
System.out.println("vector向量的當前容量為: " + vector.capacity());
// 遍歷vector向量
System.out.print("vector向量中的元素為: ");
Enumeration<String> elements = vector.elements();
while (elements.hasMoreElements()) {
System.out.print(elements.nextElement());
}
}
}
運行結(jié)果:
三.Set接口
(一)Set接口介紹
java.util.Set
接口和java.util.List
接口一樣袱瓮,同樣繼承自Collection
接口缤骨,它與Collection
接口中的方法基本一致,并沒有對Collection
接口進行功能上的擴充懂讯,只是比Collection
接口更加嚴格了荷憋。與List
接口不同的是,Set
接口中元素無序褐望,并且都會以某種規(guī)則保證存入的元素不出現(xiàn)重復(fù)。
(二)Set接口特點
- 不允許存儲重復(fù)的元素
- 沒有索引,沒有帶索引的方法,也不能使用普通的for循環(huán)遍歷
注意事項:
Set
集合沒有索引,不能用普通的for
循環(huán)遍歷,取出元素的方式可以采用:迭代器串前、增強for瘫里。
代碼:
public class SetTest {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("a");
set.add("c");
set.add("b");
set.add("d");
set.add("d");
System.out.println("set集合中元素為: " + set);
// 使用迭代器遍歷set集合元素
Iterator<String> it = set.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
System.out.println("\n=====================");
// 使用增強for循環(huán)遍歷set集合元素
for (String s : set) {
System.out.print(s + " ");
}
}
}
運行結(jié)果:
(三)Set集合的子類
1.HashSet集合
java.util.HashSet
是Set
接口的一個實現(xiàn)類,它所存儲的元素是不可重復(fù)的荡碾,并且元素都是無序的(即存取順序不一致)谨读。java.util.HashSet
底層的實現(xiàn)其實是一個java.util.HashMap
支持。
注意事項:
HashSet
是根據(jù)對象的哈希值來確定元素在集合中的存儲位置坛吁,因此具有良好的存取和查找性能劳殖。保證元素唯一性的方式依賴于:hashCode
與equals
方法铐尚。
(1) HashSet特點:
- 不允許存儲重復(fù)的元素
- 沒有索引,沒有帶索引的方法,也不能使用普通的for循環(huán)遍歷
- 是一個無序的集合,存儲元素和取出元素的順序有可能不一致
- 底層是一個哈希表結(jié)構(gòu)(查詢的速度非常的快)
2.HashSet集合存儲數(shù)據(jù)的結(jié)構(gòu)(哈希表)
(1) 哈希值
哈希值:是一個十進制的整數(shù),由系統(tǒng)隨機給出(就是對象的地址值,是一個,是模擬出來得到地址,不是數(shù)據(jù)實際存儲的物理地址)
- 在
Object
類有一個方法,可以獲取對象的哈希值 -
int hashCode()
返回該對象的哈希碼值。
代碼:
Person.java
public class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
// 重寫hashCode方法
public int hashCode() {
return Objects.hash(name, age);
}
}
HashCodeTest.java
public class HashCodeTest {
public static void main(String[] args) {
Person person1 = new Person("小明", 18);
Person person2 = new Person("小明", 18);
Person person3 = new Person("小張", 19);
System.out.println(person1 + "" + person1.hashCode());
System.out.println(person2 + "" + person2.hashCode());
System.out.println(person3 + "" + person3.hashCode());
/*
String類的哈希值
String類重寫Obejct類的hashCode方法
*/
String str1 = "abc";
String str2 = "def";
String str3 = "重地";
String str4 = "通話";
System.out.println("abc: " + str1.hashCode());
System.out.println("def: " + str2.hashCode());
System.out.println("重地: " + str3.hashCode());
System.out.println("通話: " + str4.hashCode());
System.out.println("重地==通話: " + (str3 == str4));
}
}
運行結(jié)果:
(2) 哈希表
在JDK1.8之前哆姻,哈希表底層采用實現(xiàn)宣增,即使用鏈表處理沖突,同一
hash
值的鏈表都存儲在一個鏈表里矛缨。但是當位于一個桶中的元素較多爹脾,即hash
值相等的元素較多時,通過key
值依次查找的效率較低箕昭。而JDK1.8中灵妨,哈希表存儲采用實現(xiàn),當鏈表長度超過閾值(8)時落竹,將鏈表轉(zhuǎn)換為紅黑樹泌霍,這樣大大減少了查找時間。
(3) HashSet存儲流程圖
3.HashSet集合存儲自定義類型元素
HashSet
集合元素的唯一性述召,是根據(jù)對象的hashCode
和equals
方法來決定的朱转。
給HashSet
中存放自定義類型元素時,需要重寫對象中的hashCode
和equals
方法桨武,建立自己的比較方式肋拔,才能保證HashSet
集合中的對象唯一。
代碼:
Person.java
public class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Person penson = (Person) o;
return age == penson.age &&
Objects.equals(name, penson.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
HashSetEqualsTest.java
public class HashSetEqualsTest {
public static void main(String[] args) {
Person person1 = new Person("張三", 18);
Person person2 = new Person("張三", 20);
Person person3 = new Person("李四", 18);
Person person4 = new Person("張三", 18);
HashSet<Person> set = new HashSet<>();
Collections.addAll(set, person1, person2, person3, person4);
System.out.println(set);
}
}
運行結(jié)果:
4.LinkedHashSet集合
在HashSet下面有一個子類java.util.LinkedHashSet
呀酸,它是鏈表和哈希表組合的一個數(shù)據(jù)存儲結(jié)構(gòu)凉蜂,具有可預(yù)知迭代順序的Set
接口的哈希表和鏈接列表實現(xiàn)。此實現(xiàn)與HashSet
的不同之外在于性誉,LinkedHashSet
維護著一個運行于所有條目的雙重鏈接列表窿吩。此鏈接列表定義了迭代順序,即按照將元素插入到Set集合中的順序(插入順序)進行迭代错览。
(1) LinkedHashSet特點:
底層是一個哈希表(數(shù)組+鏈表/紅黑樹)+鏈表:多了一條鏈表(記錄元素的存儲順序),保證元素有序
代碼:
public class LinkedHashSetTest {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
LinkedHashSet<String> linkedSet = new LinkedHashSet<>();
Collections.addAll(set,"張三","李四","王五","趙六");
Collections.addAll(linkedSet,"張三","李四","王五","趙六");
System.out.println(set);
System.out.println(linkedSet);
}
}
運行結(jié)果:
四.Collections工具類
(一)常用方法
java.utils.Collections
是集合工具類纫雁,用來對集合進行操作。部分方法如下:
-
public static <T> boolean addAll(Collection<T> c, T... elements)
:往集合中添加一些元素倾哺。 -
public static void shuffle(List<?> list) 打亂順序
:打亂集合順序轧邪。 -
public static <T> void sort(List<T> list)
:將集合中元素按照默認規(guī)則排序。 -
public static <T> void sort(List<T> list羞海,Comparator<? super T> )
:將集合中元素按照指定規(guī)則排序忌愚。
代碼:
public class CollectionsTest {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
// 往集合中添加一些元素
Collections.addAll(list, "李四", "張三", "王五", "趙六");
System.out.println(list);
// 打亂順序
Collections.shuffle(list);
System.out.println(list);
// 按照自然順序排序
Collections.sort(list);
System.out.println(list);
}
}
運行結(jié)果:
(二)實現(xiàn)Comparable接口自定義排序
1.sort(List<T> list)使用前提
被排序的集合里邊存儲的元素,必須實現(xiàn)Comparable
接口,重寫接口中的方法compareTo()
定義排序的規(guī)則。
2.Comparable接口的排序規(guī)則:
- 自己(this)-參數(shù)(對象):升序
- 參數(shù)(對象)-自己(this):降序
代碼:
Student.java
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return name + ": " + age;
}
@Override
public int compareTo(Student o) {
int result = this.age - o.age; // 按年齡升序
// int result = o.age-this.age; // 按年齡降序
if (result == 0) {
result = this.name.charAt(0) - o.name.charAt(0); // 按姓名升序
}
return result;
}
}
SortComparableTest.java
public class SortComparableTest {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("abc", 18));
list.add(new Student("jack", 20));
list.add(new Student("tom", 30));
list.add(new Student("rose", 18));
list.add(new Student("mark", 15));
System.out.println("排序前:\n" + list);
Collections.sort(list);
System.out.println("按年齡升序,姓名升序排序后:\n" + list);
}
}
運行結(jié)果:
(三)實現(xiàn)Comparator接口自定義排序
1.Comparator接口概述
public static <T> void sort(List<T> list却邓,Comparator<? super T> )
里面涉及到了Comparator
這個接口硕糊,該接口位于位于java.util
包下。
排序是comparator
能實現(xiàn)的功能之一,該接口代表一個比較器,比較器具有可比性简十。
重寫Comparator
比較的方法:public int compare(String o1, String o2)
來比較其兩個參數(shù)的順序檬某。
2.Comparator的排序規(guī)則:
public int compare(String o1, String o2)
:比較其兩個參數(shù)的順序。
兩個對象比較的結(jié)果有三種:大于螟蝙,等于恢恼,小于。
如果要按照升序排序:
o1大于o2返回(正數(shù))胶逢,相等返回0厅瞎,o1小于o2返回(負數(shù))
如果要按照降序排序:
o1小于o2返回(正數(shù)),相等返回0初坠,o1小于o2返回(正數(shù))
- o1-o2:升序
- o2-o1:降序
代碼:
student.java
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return name + ": " + age;
}
}
SortComparatorTest.java
public class SortComparatorTest {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("abc", 18));
list.add(new Student("jack", 20));
list.add(new Student("tom", 30));
list.add(new Student("rose", 18));
list.add(new Student("mark", 15));
System.out.println("排序前:\n" + list);
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int result = o1.getAge() - o2.getAge(); // 按年齡升序
if (result == 0) {
result = o1.getName().charAt(0) - o2.getName().charAt(0); // 按姓名升序
}
return result;
}
});
System.out.println("按年齡升序,姓名升序排序后:\n" + list);
}
}
運行結(jié)果:
(四)Comparator和Comparable的區(qū)別
1.API文檔
Comparable:強行對實現(xiàn)它的每個類的對象進行整體排序和簸。這種排序被稱為類的自然排序,類的compareTo方法被稱為它的自然比較方法碟刺。只能在類中實現(xiàn)compareTo()一次锁保,不能經(jīng)常修改類的代碼實現(xiàn)自己想要的排序。實現(xiàn)此接口的對象列表(和數(shù)組)可以通過Collections.sort(和Arrays.sort)進行自動排序半沽,對象可以用作有序映射中的鍵或有序集合中的元素爽柒,無需指定比較器。
Comparator強行對某個對象進行整體排序者填『拼澹可以將Comparator 傳遞給sort方法(如Collections.sort或 Arrays.sort),從而允許在排序順序上實現(xiàn)精確控制占哟。還可以使用Comparator來控制某些數(shù)據(jù)結(jié)構(gòu)(如有序set或有序映射)的順序心墅,或者為那些沒有自然順序的對象collection提供排序。
2.簡單理解
-
Comparable
:自己(this)和別人(參數(shù))比較,自己(this)需要實現(xiàn)Comparable
接口,重寫比較的規(guī)則compareTo
方法 -
Comparator
:相當于找一個第三方的裁判,比較兩個,sort
方法需要實現(xiàn)Comparator
接口,重寫比較的規(guī)則compare
方法