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)
:將集合中元素按照默認規則排序。public static <T> void sort(List<T> list,Comparator<? super T> )
:將集合中元素按照指定規則排序。
代碼演示:
javabean標準類:
package Text_02_commections工具類;
public class Person implements Comparable <Person>{
private String name;
private 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 int compareTo(Person o) {
//return 0;//認爲元素都是相同的
//自定義比較的規則,比較兩個人的年齡(this,參數Person)
return this.getAge() - o.getAge();//年齡升序排序
//return o.getAge() - this.getAge();//年齡升序排序
}
}
package Text_02_commections工具類;
import java.util.ArrayList;
import java.util.Collections;
/**
* @author
* @version 1.0
* @date 2020/6/10 15:30
* addAll(Collection<? super T> c, T... elements) 將所有指定的元素添加到指定的集合。
*shuffle(List<?> list) 使用默認的隨機源隨機排列指定的列表。
*sort(List<T> list) 根據其元素的natural ordering對指定的列表進行排序。
*sort(List<T> list, Comparator<? super T> c) 根據指定的比較器引起的順序對指定的列表進行排序。
*
*/
public class connections {
public static void main(String[] args) {
//定義一個集合
ArrayList<Integer> list = new ArrayList<>();
//collection方法add()
list.add(1);
list.add(2);
list.add(3);
System.out.println(list);//[1, 2, 3]
//addAll(Collection<? super T> c, T... elements) 將所有指定的元素添加到指定的集合。
Collections.addAll(list,1,2,3,4,5,6);//批量放入集合元素
System.out.println(list);//[1, 2, 3, 1, 2, 3, 4, 5, 6]
//shuffle(List<?> list) 使用默認的隨機源隨機排列指定的列表。
Collections.shuffle(list);//查看api shuffle是靜態方法所有可以直接調用
System.out.println(list);//[4, 3, 1, 2, 3, 5, 6, 1, 2]每次執行順序都會不同
//sort(List<T> list) 根據其元素的natural ordering對指定的列表進行排序。
Collections.sort(list);
System.out.println(list);//[1, 1, 2, 2, 3, 3, 4, 5, 6]
//自定義類型
ArrayList<Person> people = new ArrayList<>();
//添加元素
people.add(new Person("張三",19));
people.add(new Person("李四",17));
people.add(new Person("王五",18));
//排序
//Collections.sort(people);//不對無法排序,程序不知道按penper這麼排序所有不能這樣寫,那該這麼辦呢?看源代碼知
//須實現comporeto接口
/* public static <T> void sort(List<T> list):將集合中元素按照默認規則排序。
注意:
sort(List<T> list)使用前提 被排序的集合裏邊存儲的元素,必須實現Comparable,重寫接口中的方法compareTo定義排序的規則
Comparable接口的排序規則:
自己(this)-參數:升序*/
Collections.sort(people);//按年齡排序
System.out.println("實現接口後排序結果"+people);
}
}
代碼結果:
[1, 2, 3]
[1, 2, 3, 1, 2, 3, 4, 5, 6]
[5, 2, 6, 1, 2, 3, 1, 4, 3]
[1, 1, 2, 2, 3, 3, 4, 5, 6]
實現接口後排序結果[Person{name='李四', age=17}, Person{name='王五', age=18}, Person{name='張三', age=19}]
代碼演示之後 ,發現我們的集合按照順序進行了排列,可是這樣的順序是採用默認的順序,如果想要指定順序那該怎麼辦呢?
public static <T> void sort(List<T> list,Comparator<? super T> )
:將集合中元素按照指定規則排序。接下來講解一下指定規則的排列。
Comparator比較器
先研究這個方法
public static <T> void sort(List<T> list)
:將集合中元素按照默認規則排序。
不過這次存儲的是字符串類型。
public class CollectionsDemo2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("cba");
list.add("aba");
list.add("sba");
list.add("nba");
//排序方法
Collections.sort(list);
System.out.println(list);
}
}
結果:
[aba, cba, nba, sba]
我們使用的是默認的規則完成字符串的排序,那麼默認規則是怎麼定義出來的呢?
說到排序了,簡單的說就是兩個對象之間比較大小,那麼在JAVA中提供了兩種比較實現的方式,一種是比較死板的採用java.lang.Comparable
接口去實現,一種是靈活的當我需要做排序的時候在去選擇的java.util.Comparator
接口完成。
那麼我們採用的public static <T> void sort(List<T> list)
這個方法完成的排序,實際上要求了被排序的類型需要實現Comparable接口完成比較的功能,在String類型上如下:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
String類實現了這個接口,並完成了比較規則的定義,但是這樣就把這種規則寫死了,那比如我想要字符串按照第一個字符降序排列,那麼這樣就要修改String的源代碼,這是不可能的了,那麼這個時候我們可以使用
public static <T> void sort(List<T> list,Comparator<? super T> )
方法靈活的完成,這個裏面就涉及到了Comparator這個接口,位於位於java.util包下,排序是comparator能實現的功能之一,該接口代表一個比較器,比較器具有可比性!顧名思義就是做排序的,通俗地講需要比較兩個對象誰排在前誰排在後,那麼比較的方法就是:
-
public int compare(String o1, String o2)
:比較其兩個參數的順序。兩個對象比較的結果有三種:大於,等於,小於。
如果要按照升序排序,
則o1 小於o2,返回(負數),相等返回0,01大於02返回(正數)
如果要按照降序排序
則o1 小於o2,返回(正數),相等返回0,01大於02返回(負數)
操作如下:
public class CollectionsDemo3 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("cba");
list.add("aba");
list.add("sba");
list.add("nba");
//排序方法 按照第一個單詞的降序
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.charAt(0) - o1.charAt(0);
}
});
System.out.println(list);
}
}
結果如下:
[sba, nba, cba, aba]
簡述Comparable和Comparator兩個接口的區別。
Comparable:強行對實現它的每個類的對象進行整體排序。這種排序被稱爲類的自然排序,類的compareTo方法被稱爲它的自然比較方法。只能在類中實現compareTo()一次,不能經常修改類的代碼實現自己想要的排序。實現此接口的對象列表(和數組)可以通過Collections.sort(和Arrays.sort)進行自動排序,對象可以用作有序映射中的鍵或有序集合中的元素,無需指定比較器。
Comparator強行對某個對象進行整體排序。可以將Comparator 傳遞給sort方法(如Collections.sort或 Arrays.sort),從而允許在排序順序上實現精確控制。還可以使用Comparator來控制某些數據結構(如有序set或有序映射)的順序,或者爲那些沒有自然順序的對象collection提供排序。
練習
創建一個學生類,存儲到ArrayList集合中完成指定排序操作。
Student 初始類
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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
測試類:
public class Demo {
public static void main(String[] args) {
// 創建四個學生對象 存儲到集合中
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("rose",18));
list.add(new Student("jack",16));
list.add(new Student("abc",16));
list.add(new Student("ace",17));
list.add(new Student("mark",16));
/*
讓學生 按照年齡排序 升序
*/
// Collections.sort(list);//要求 該list中元素類型 必須實現比較器Comparable接口
for (Student student : list) {
System.out.println(student);
}
}
}
發現,當我們調用Collections.sort()方法的時候 程序報錯了。
原因:如果想要集合中的元素完成排序,那麼必須要實現比較器Comparable接口。
於是我們就完成了Student類的一個實現,如下:
public class Student implements Comparable<Student>{
....
@Override
public int compareTo(Student o) {
return this.age-o.age;//升序
}
}
再次測試,代碼就OK 了效果如下:
Student{name='jack', age=16}
Student{name='abc', age=16}
Student{name='mark', age=16}
Student{name='ace', age=17}
Student{name='rose', age=18}
擴展
如果在使用的時候,想要獨立的定義規則去使用 可以採用Collections.sort(List list,Comparetor c)方式,自己定義規則:
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.getAge()-o1.getAge();//以學生的年齡降序
}
});
效果:
Student{name='rose', age=18}
Student{name='ace', age=17}
Student{name='jack', age=16}
Student{name='abc', age=16}
Student{name='mark', age=16}
如果想要規則更多一些,可以參考下面代碼:
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 年齡降序
int result = o2.getAge()-o1.getAge();//年齡降序
if(result==0){//第一個規則判斷完了 下一個規則 姓名的首字母 升序
result = o1.getName().charAt(0)-o2.getName().charAt(0);
}
return result;
}
});
效果如下:
Student{name='rose', age=18}
Student{name='ace', age=17}
Student{name='abc', age=16}
Student{name='jack', age=16}
Student{name='mark', age=16}