java中Comparable和Comparator的用法和區別 Comparable自然排序 Comparator比較器排序
一、概述
Comparable和Comparator在java中都是用於來比較數據大小。實現Comparable接口需要重寫compareTo方法,實現Comparator方法需要重寫compare方法。 這兩個方法返回值都是int類型,根據返回值來判斷比較對象的大小,從而實現排序。
二、Comparable 接口比較
1、Comparable接口位於java.lang.Comparable<T>,下面用代碼來演示Comparable接口排序。
2、定義一個 Student 學生類,如下:
/**
* description: 定義Student 學生類
* @version v1.0
* @author w
* @date 2019年10月31日下午10:10:34
**/
public class Student {
private String name ; // 姓名
private int age ; // 年齡
private double score ; // 分數
// ignore getter , setter
public Student(String name, int age, double score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
public Student() {
super();
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
}
}
3、定義 StudentCompareable類,繼承Student , 實現 Comparable接口,重寫CompareTo方法。
/**
* description: StudentCompareable類,繼承Student , 實現 Comparable接口,重寫CompareTo方
* @version v1.0
* @author w
* @date 2019年11月3日下午2:16:31
**/
public class StudentComparable extends Student implements Comparable<StudentComparable> {
@Override
public int compareTo(StudentComparable o) {
/**
* 需求: age 年齡從 小到大 排列, score 分數從 大 到 小 排列
*/
if(this.getAge()-o.getAge() ==0) {
// 年齡相同,判斷分數 .
//注意分數是大到小排列, 所以是 o.getScore() - this.getScore()。
return (int) (o.getScore() - this.getScore());
}else {
return this.getAge()-o.getAge();
}
}
public StudentComparable() {
super();
}
public StudentComparable(String name, int age, double score) {
super(name, age, score);
}
}
4、定義 StudentComparableTest 類,測試排序功能
/**
* description: 測試 Compareable 排序
* @version v1.0
* @author w
* @date 2019年11月3日下午2:16:31
**/
public class StudentComparableTest {
@Test
public void test() {
StudentComparable s1 = new StudentComparable("小明", 18, 60D);
StudentComparable s2 = new StudentComparable("小紅", 15, 90D);
StudentComparable s3 = new StudentComparable("小剛", 22, 80D);
StudentComparable s4 = new StudentComparable("小剛", 22, 85D);
List<StudentComparable> list = new ArrayList<StudentComparable>();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
// 排序前
System.out.println(list);
Collections.sort(list);
// 排序後
System.out.println(list);
}
}
5、結果如下:
[Student [name=小明, age=18, score=60.0], Student [name=小紅, age=15, score=90.0], Student [name=小剛, age=22, score=80.0], Student [name=小剛, age=22, score=85.0]]
[Student [name=小紅, age=15, score=90.0], Student [name=小明, age=18, score=60.0], Student [name=小剛, age=22, score=85.0], Student [name=小剛, age=22, score=80.0]]
6、根據排序前後的結果,可以看到 年齡是從小到大正序排序的,分數是從大到小倒序排序,達到預期結果。
三、Comparator 接口排序
1、Comparator接口位於java.util.Comparator<T>,下面用代碼來演示Comparator接口排序。
2、定義StudentComparator類 繼承Student類,實現 Comparator接口,重寫compare方法。
/**
* description: 定義StudentComparator類 繼承Student類,實現 Comparator接口,重寫compare方法
* @version v1.0
* @author w
* @date 2019年11月3日下午5:12:42
**/
public class StudentComparator extends Student implements Comparator<StudentComparator> {
@Override
public int compare(StudentComparator o1, StudentComparator o2) {
/**
* age 年齡,正序 小到大 , score 分數倒序 大到小。
*/
if(o1.getAge()==o2.getAge()) {
// 注意:分數是 倒序 大到小,所以是 o2-o1.
return (int) (o2.getScore() - o1.getScore()) ;
}else {
return o1.getAge() - o2.getAge();
}
}
public StudentComparator() {
super();
}
public StudentComparator(String name, int age, double score) {
super(name, age, score);
}
}
3、定義 StudentComparatorTest 類,測試排序功能
/**
* description: 測試Comparator
* @version v1.0
* @author w
* @date 2019年11月3日下午9:29:43
**/
public class StudentComparatorTest {
@Test
public void test() {
StudentComparator s1 = new StudentComparator("小明", 18, 60D);
StudentComparator s2 = new StudentComparator("小紅", 15, 90D);
StudentComparator s3 = new StudentComparator("小剛", 22, 80D);
StudentComparator s4 = new StudentComparator("小剛", 22, 85D);
List<StudentComparator> list = new ArrayList<StudentComparator>();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
// 排序前
System.out.println(list);
Collections.sort(list,new StudentComparator());
// 排序後
System.out.println(list);
}
}
4、結果如下:
[Student [name=小明, age=18, score=60.0], Student [name=小紅, age=15, score=90.0], Student [name=小剛, age=22, score=80.0], Student [name=小剛, age=22, score=85.0]]
[Student [name=小紅, age=15, score=90.0], Student [name=小明, age=18, score=60.0], Student [name=小剛, age=22, score=85.0], Student [name=小剛, age=22, score=80.0]]
5、根據排序前後的結果,可以看到 年齡是從小到大正序排序的,分數是從大到小倒序排序,達到預期結果。
6、增加一個測試:按照分數大到小的排序 (結果略)
/**
* description: 按照分數大到小的排序
* @return void
* @version v1.0
* @author w
* @date 2019年11月3日 下午9:34:03
*/
@Test
public void testScore() {
StudentComparator s1 = new StudentComparator("小明", 18, 60D);
StudentComparator s2 = new StudentComparator("小紅", 15, 90D);
StudentComparator s3 = new StudentComparator("小剛", 22, 80D);
StudentComparator s4 = new StudentComparator("小剛", 22, 85D);
List<StudentComparator> list = new ArrayList<StudentComparator>();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
// 排序前
System.out.println(list);
Collections.sort(list, new Comparator<StudentComparator>() {
@Override
public int compare(StudentComparator o1, StudentComparator o2) {
return (int) (o2.getScore() - o1.getScore());
}
});
// 排序後
System.out.println(list);
}
四、總結
1、Comparable 位於 java.lang 包, Comparator 位於 java.util 包。
2、實現Comparable接口需要重寫compareTo方法,實現Comparator方法需要重寫compare方法, 這兩個方法返回值都是int類型。
3、 int result = s1.compareTo(s2); result = 0 , 則 s1=s2 ; result < 0, 則 s1<s2 ; result > 0 , 則 s1 > s2 。
4、int result = compare(T o1, T o2); 結果同上。 (若是 o2-o1,則反之。)
5、Comparable 接口,java中大部分類已經實現了Comparable(String,BigDecimal,java.util.Date等),用於比較兩個對象大小,十分方便。 稱之爲 自然排序。
6、Comparator 接口,主要用集合中排序(TreeSet ,TreeMap , Collections.sort()),不同需求的排序方式,直接接口實現,易於功能擴展,不影響原代碼。 稱之爲 比較器排序。