Java對象比較-Comparable和Comparator接口使用


最近在學習貪心算法和動態規划的過程中,里面有一段自然排序的操作,順便簡單了解一下Java中對象比較后排序要使用的兩個接口:Comparable和Comparator。如果是數字,直接比較就行,但是如果是對象,如何比較后排序呢?就需要用到這兩個接口了,並且將自己定義的類作為參數傳入接口泛型,在接口里重寫比較方法,將自己要選擇排序的類屬性添加到比較條件中去。

接口主要區別

(1)Comparable接口是在java.lang下,Comparator接口是在java.util下。

(2)如果在定義類時,就實現了Comparable接口,直接在里面重寫compareTo()方法,如果沒實現,后面在業務開發中需要有比較排序的功能,就再單獨寫一個類實現Comparator接口,在里面重寫compare()方法,然后這個類需要作為參數傳入到工具類Collections.sort和Arrays.sort方法中。

(3)實現Comparable接口的類必須是自然排序,另外一個不是強制條件。

使用Comparable

(1)定義實現類時,實現Comparable接口。

 1 /**
 2  * 實體類,實現Comparable接口
 3  */
 4 public class Person implements Comparable<Person>{
 5 
 6     //屬性
 7     private String name;
 8     private int age;
 9     private int salary;
10 
11     //get和set方法
12     public String getName() {
13         return name;
14     }
15 
16     public void setName(String name) {
17         this.name = name;
18     }
19 
20     public int getAge() {
21         return age;
22     }
23 
24     public void setAge(int age) {
25         this.age = age;
26     }
27 
28     public int getSalary() {
29         return salary;
30     }
31 
32     public void setSalary(int salary) {
33         this.salary = salary;
34     }
35 
36     //構造方法
37     public Person(String name, int age, int salary) {
38         this.name = name;
39         this.age = age;
40         this.salary = salary;
41     }
42 
43     @Override
44     public String toString() {
45         return "Person{" +
46                 "name='" + name + '\'' +
47                 ", age=" + age +
48                 ", salary=" + salary +
49                 '}';
50     }
51 
52     //重寫接口方法,o為要比較的對象
53     @Override
54     public int compareTo(Person o) {
55         //大於要比較的對象就返回1
56         if(this.salary>o.getSalary()){
57             return 1;
58         }
59         //小於則返回-1
60         else if(this.salary<o.getSalary()){
61             return -1;
62         }
63         //相等則返回0
64         return 0;
65     }
66 }

(2)測試類,來查看是否按照自定義的屬性進行自然排序。

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.List;
 4 
 5 public class TestComparable {
 6 
 7     public static void main(String[] args) {
 8         //測試Comparable接口
 9         Person p1=new Person("clyang",18,4000);
10         Person p2=new Person("messi",30,8000);
11         Person p3=new Person("ronald",32,9000);
12         Person p4=new Person("herry",19,7600);
13         Person p5=new Person("roben",35,7900);
14 
15         //添加到集合
16         List<Person> list=new ArrayList<>();
17         list.add(p1);
18         list.add(p2);
19         list.add(p3);
20         list.add(p4);
21         list.add(p5);
22 
23         System.out.println("-----------------排序前-----------------");
24         for (Person person : list) {
25             System.out.println(person);
26         }
27 
28         //排序一般使用Collections.sort方法,或者使用Arrays.sort方法,按照比較的元素進行自然排序,即從小到大
29         Collections.sort(list);
30 
31         System.out.println("-----------------排序后-----------------");
32         for (Person person : list) {
33             System.out.println(person);
34         }
35 
36     }
37 }

控制台輸出情況,發現正常的按照工資進行了自然排序,即升序排列。

使用Comparator

使用這個接口時,創建類的時候可以不實現接口,需要單獨創建一個類來實現這個接口。

(1)創建類

 1 /**
 2  * 實體類,不實現Comparable接口,使用單獨的Comparator接口
 3  */
 4 public class Staff {
 5 
 6     //屬性
 7     private String name;
 8     private int age;
 9     private int salary;
10 
11     public Staff(String name, int age, int salary) {
12         this.name = name;
13         this.age = age;
14         this.salary = salary;
15     }
16 
17     public String getName() {
18         return name;
19     }
20 
21     public void setName(String name) {
22         this.name = name;
23     }
24 
25     public int getAge() {
26         return age;
27     }
28 
29     public void setAge(int age) {
30         this.age = age;
31     }
32 
33     public int getSalary() {
34         return salary;
35     }
36 
37     public void setSalary(int salary) {
38         this.salary = salary;
39     }
40 
41     @Override
42     public String toString() {
43         return "Staff{" +
44                 "name='" + name + '\'' +
45                 ", age=" + age +
46                 ", salary=" + salary +
47                 '}';
48     }
49 }
View Code

(2)創建實現接口的類,重寫里面的比較方法,這屬於泛型在接口中的一種使用方法,即接口泛型是什么,實現類里面就是什么泛型。

 1 import java.util.Comparator;
 2 
 3 /**
 4  * 單獨寫的比較器,實現Compartor接口
 5  */
 6 public class StaffComparator implements Comparator<Staff> {
 7 
 8     //不一定要自然排序即升序,可以反過來寫成降序
 9     @Override
10     public int compare(Staff o1, Staff o2) {
11         //降序
12         /*if(o1.getSalary()>o2.getSalary()){
13             return -1;
14         }
15         if(o1.getSalary()<o2.getSalary()){
16             return 1;
17         }
18         return 0;*/
19 
20         //升序
21         /*if(o1.getSalary()>o2.getSalary()){
22             return 1;
23         }
24         if(o1.getSalary()<o2.getSalary()){
25             return -1;
26         }
27         return 0;*/
28 
29         //先按照年齡倒序排,如果年齡相等比較工資
30         if(o1.getAge()>o2.getAge()){
31             return -1;
32         }
33         if(o1.getAge()<o2.getAge()){
34             return 1;
35         }
36         //能到這里說明年齡相等,繼續比較工資
37         if(o1.getSalary()>o2.getSalary()){
38             return 1;
39         }
40         if(o1.getSalary()<o2.getSalary()){
41             return -1;
42         }
43         return 0;
44     }
45 }

測試類,來查看是否按照自己的要求來排序。

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.Comparator;
 4 import java.util.List;
 5 
 6 public class TestComparator {
 7 
 8     public static void main(String[] args) {
 9         //測試Comparator接口
10         Staff p1=new Staff("clyang",18,4000);
11         Staff p2=new Staff("messi",30,8000);
12         Staff p3=new Staff("ronald",32,9000);
13         Staff p4=new Staff("herry",18,7600);
14         Staff p5=new Staff("roben",35,7900);
15 
16         //添加到集合
17         List<Staff> list=new ArrayList<>();
18         list.add(p1);
19         list.add(p2);
20         list.add(p3);
21         list.add(p4);
22         list.add(p5);
23 
24         System.out.println("-----------------排序前-----------------");
25         for (Staff staff : list) {
26             System.out.println(staff);
27         }
28 
29         //排序,需要使用自定義比較類
30         Comparator myComparator=new StaffComparator();
31         Collections.sort(list,myComparator);
32 
33         System.out.println("-----------------排序后-----------------");
34         for (Staff staff : list) {
35             System.out.println(staff);
36         }
37     }
38 }

控制台輸出情況,可以發現,先是按照年齡進行了倒排序,當排到clyang和herry的時候,由於年齡相同,因此繼續按照工資來升排序。

以上是兩種接口的使用方法,也是參考了博主的文章學習的,以后可以拿來用。

參考博文:

(1)https://www.cnblogs.com/Kevin-mao/p/5912775.html

(2)https://www.cnblogs.com/youngchaolin/p/11029505.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM