Java中比較器是排序、加入有序數(shù)組等操作的時(shí)候必須要有的,沒有的話會(huì)報(bào)錯(cuò),例如下面這段代碼:
package dataStructure.heap;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeMap;
public class MyComparatorTest {
public static void main(String[] args) {
Student[] students = {new Student(2, "student2", 20),
new Student(2, "student3", 30), new Student(4, "student4", 40)};
//這里如果只寫students數(shù)組而不傳入比較器的話會(huì)報(bào)錯(cuò)
Arrays.sort(students);
}
}
class Student {
int age;
String name;
int id;
public Student(int age, String name, int id) {
this.age = age;
this.name = name;
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
運(yùn)行時(shí)會(huì)發(fā)生下面的異常
Exception in thread "main" java.lang.ClassCastException: dataStructure.heap.Student cannot be cast to java.lang.Comparable
?? ?at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
?? ?at java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
?? ?at java.util.Arrays.sort(Arrays.java:1246)
?? ?at dataStructure.heap.MyComparatorTest.main(MyComparatorTest.java:13)
Process finished with exit code 1
這個(gè)sort方法是可以只傳入數(shù)組(數(shù)組中的類型是基礎(chǔ)類型或者已經(jīng)實(shí)現(xiàn)了Comparable了),也可以傳入兩個(gè)參數(shù):數(shù)組和數(shù)組中類型的比較器
比較器實(shí)現(xiàn)有兩種方式,
一種是當(dāng)前類實(shí)現(xiàn)了java.lang.Comparable接口,這個(gè)時(shí)候當(dāng)前類需要實(shí)現(xiàn)下面這個(gè)方法:
@Override public int compareTo(Object o) { return 0; }
這種方式只有一種比較方式,比較死板,一般我不會(huì)使用(雖然也可以疊加比較器,疊加比較器的時(shí)候相當(dāng)于這是一種默認(rèn)的,傳了使用比較器,沒有傳使用這個(gè))
第二種方式是:寫一個(gè)比較器類繼承Comparator,范型是當(dāng)前類型(也可以不寫比較器類而在使用的時(shí)候直接傳入Lambda表達(dá)式)
改造之后的類如下:
package dataStructure.heap;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeMap;
public class MyComparatorTest {
public static void main(String[] args) {
Student[] students = {new Student(2, "student2", 20),
new Student(2, "student3", 30), new Student(4, "student4", 40)};
//這里如果只寫students數(shù)組而不傳入比較器的話會(huì)報(bào)錯(cuò)
//第二個(gè)參數(shù)是比較器類或者Lambda表達(dá)式
Arrays.sort(students, new AgeAscComparator());
Arrays.sort(students, (a, b) -> a.age - b.age);
for (Student student : students) {
System.out.println(student);
}
}
}
class AgeAscIdDescComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age == o2.age ? o2.id - o1.id : o1.age - o2.age;
}
}
class AgeAscComparator implements Comparator<Student> {
//這個(gè)是必須實(shí)現(xiàn)的方法,所有的比較器都需要遵循以下規(guī)律:
//1.返回負(fù)數(shù)的時(shí)候,認(rèn)為第一個(gè)參數(shù)應(yīng)該排在前面,例如數(shù)字類型的誰小誰在前
//2.返回正數(shù)的時(shí)候,認(rèn)為第二個(gè)參數(shù)應(yīng)該排在前面,例如數(shù)字類型的誰大誰在前
//3.返回0的時(shí)候,無所謂誰排在前面
@Override
public int compare(Student o1, Student o2) {
/**
* 這一句話也可以替換為:if(o1.age < o2.age) {
* return -1;
* } else if(o1.age > o2.age) {
* return 1;
* } else {
* return 0;
* }
*/
return o1.age - o2.age;
}
}
class Student {
int age;
String name;
int id;
public Student(int age, String name, int id) {
this.age = age;
this.name = name;
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", id=" + id +
'}';
}
}
運(yùn)行結(jié)果:
Student{age=2, name='student2', id=20}
Student{age=2, name='student3', id=30}
Student{age=4, name='student4', id=40}
Process finished with exit code 0
這里我們看到其實(shí)age排序并不能明確區(qū)分student2還是student3在前
使用第二種方式寫更復(fù)雜一點(diǎn)的比較器類(多個(gè)字段比較或者同一個(gè)字段相同的時(shí)候區(qū)別先后順序)
class AgeAscIdDescComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
//如果age相同,按id降序
//如果age不同,按age升序
return o1.age == o2.age ? o2.id - o1.id : o1.age - o2.age;
}
}
傳入這個(gè)比較器的時(shí)候運(yùn)行結(jié)果如下(確定age相同的時(shí)候id大的在前):文章來源:http://www.zghlxwxcb.cn/news/detail-424776.html
Student{age=2, name='student3', id=30}
Student{age=2, name='student2', id=20}
Student{age=4, name='student4', id=40}文章來源地址http://www.zghlxwxcb.cn/news/detail-424776.html
到了這里,關(guān)于認(rèn)識(shí)比較器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!