java中Comparable和Comparator的用法和區別 Comparable自然排序 Comparator比較器排序

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()),不同需求的排序方式,直接接口實現,易於功能擴展,不影響原代碼。 稱之爲 比較器排序

 

BigDecimal 比較大小

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章