一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|

服務器之家 - 編程語言 - JAVA教程 - Java Comparable 和 Comparator 的詳解及區別

Java Comparable 和 Comparator 的詳解及區別

2020-07-09 10:32張拭心 JAVA教程

這篇文章主要介紹了Java Comparable 和 Comparator 的詳解及區別的相關資料,Comparable 自然排序和Comparator 定制排序的實例,需要的朋友可以參考下

Java ComparableComparator 的詳解及區別

Java 中為我們提供了兩種比較機制:Comparable 和 Comparator,他們之間有什么區別呢?今天來了解一下。

Comparable 自然排序

Comparable 在 java.lang 包下,是一個接口,內部只有一個方法 compareTo():

?
1
2
3
public interface Comparable<T> {
  public int compareTo(T o);
}

Comparable 可以讓實現它的類的對象進行比較,具體的比較規則是按照 compareTo 方法中的規則進行。這種順序稱為 自然順序。

compareTo 方法的返回值有三種情況:

  1. e1.compareTo(e2) > 0 即 e1 > e2
  2. e1.compareTo(e2) = 0 即 e1 = e2
  3. e1.compareTo(e2) < 0 即 e1 < e2

注意:

1.由于 null 不是一個類,也不是一個對象,因此在重寫 compareTo 方法時應該注意 e.compareTo(null) 的情況,即使 e.equals(null) 返回 false,compareTo 方法也應該主動拋出一個空指針異常 NullPointerException。

2.Comparable 實現類重寫 compareTo 方法時一般要求 e1.compareTo(e2) == 0 的結果要和 e1.equals(e2) 一致。這樣將來使用 SortedSet 等根據類的自然排序進行排序的集合容器時可以保證保存的數據的順序和想象中一致。
有人可能好奇上面的第二點如果違反了會怎樣呢?

舉個例子,如果你往一個 SortedSet 中先后添加兩個對象 a 和 b,a b 滿足 (!a.equals(b) && a.compareTo(b) == 0),同時也沒有另外指定個 Comparator,那當你添加完 a 再添加 b 時會添加失敗返回 false, SortedSet 的 size 也不會增加,因為在 SortedSet 看來它們是相同的,而 SortedSet 中是不允許重復的。

實際上所有實現了 Comparable 接口的 Java 核心類的結果都和 equlas 方法保持一致。
實現了 Comparable 接口的 List 或則數組可以使用 Collections.sort() 或者 Arrays.sort() 方法進行排序。

實現了 Comparable 接口的對象才能夠直接被用作 SortedMap (SortedSet) 的 key,要不然得在外邊指定 Comparator 排序規則。

因此自己定義的類如果想要使用有序的集合類,需要實現 Comparable 接口,比如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
**
 * description: 測試用的實體類 書, 實現了 Comparable 接口,自然排序
 * <br/>
 * author: shixinzhang
 * <br/>
 * data: 10/5/2016
 */
public class BookBean implements Serializable, Comparable {
  private String name;
  private int count;
 
 
  public BookBean(String name, int count) {
    this.name = name;
    this.count = count;
  }
 
  public String getName() {
    return name;
  }
 
  public void setName(String name) {
    this.name = name;
  }
 
  public int getCount() {
    return count;
  }
 
  public void setCount(int count) {
    this.count = count;
  }
 
  /**
   * 重寫 equals
   * @param o
   * @return
   */
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof BookBean)) return false;
 
    BookBean bean = (BookBean) o;
 
    if (getCount() != bean.getCount()) return false;
    return getName().equals(bean.getName());
 
  }
 
  /**
   * 重寫 hashCode 的計算方法
   * 根據所有屬性進行 迭代計算,避免重復
   * 計算 hashCode 時 計算因子 31 見得很多,是一個質數,不能再被除
   * @return
   */
  @Override
  public int hashCode() {
    //調用 String 的 hashCode(), 唯一表示一個字符串內容
    int result = getName().hashCode();
    //乘以 31, 再加上 count
    result = 31 * result + getCount();
    return result;
  }
 
  @Override
  public String toString() {
    return "BookBean{" +
        "name='" + name + '\'' +
        ", count=" + count +
        '}';
  }
 
  /**
   * 當向 TreeSet 中添加 BookBean 時,會調用這個方法進行排序
   * @param another
   * @return
   */
  @Override
  public int compareTo(Object another) {
    if (another instanceof BookBean){
      BookBean anotherBook = (BookBean) another;
      int result;
 
      //比如這里按照書價排序
      result = getCount() - anotherBook.getCount();  
 
     //或者按照 String 的比較順序
     //result = getName().compareTo(anotherBook.getName());
 
      if (result == 0){  //當書價一致時,再對比書名。 保證所有屬性比較一遍
        result = getName().compareTo(anotherBook.getName());
      }
      return result;
    }
    // 一樣就返回 0
    return 0;
  }

上述代碼還重寫了 equlas(), hashCode() 方法,自定義的類想要進行比較時都要重寫這些方法。

后面重寫 compareTo 時,要判斷某個相同時對比下一個屬性,把所有屬性都比較一次。

Comparable 接口屬于 Java 集合框架的一部分。

Comparator 定制排序

Comparator 在 java.util 包下,也是一個接口,JDK 1.8 以前只有兩個方法:

?
1
2
3
4
5
6
public interface Comparator<T> {
 
  public int compare(T lhs, T rhs);
 
  public boolean equals(Object object);
}

JDK 1.8 以后又新增了很多方法:

Java Comparable 和 Comparator 的詳解及區別

基本上都是跟 Function 相關的,這里暫不介紹 1.8 新增的。

從上面內容可知使用自然排序需要類實現 Comparable,并且在內部重寫 comparaTo 方法。

而 Comparator 則是在外部制定排序規則,然后作為排序策略參數傳遞給某些類,比如 Collections.sort(), Arrays.sort(), 或者一些內部有序的集合(比如 SortedSet,SortedMap 等)。

使用方式主要分三步:

1.創建一個 Comparator 接口的實現類,并賦值給一個對象

在 compare 方法中針對自定義類寫排序規則

2.將 Comparator 對象作為參數傳遞給 排序類的某個方法

3.向排序類中添加 compare 方法中使用的自定義類

舉個例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 1.創建一個實現 Comparator 接口的對象
   Comparator comparator = new Comparator() {
     @Override
     public int compare(Object object1, Object object2) {
       if (object1 instanceof NewBookBean && object2 instanceof NewBookBean){
         NewBookBean newBookBean = (NewBookBean) object1;
         NewBookBean newBookBean1 = (NewBookBean) object2;
         //具體比較方法參照 自然排序的 compareTo 方法,這里只舉個栗子
         return newBookBean.getCount() - newBookBean1.getCount();
       }
       return 0;
     }
   };
 
   //2.將此對象作為形參傳遞給 TreeSet 的構造器中
   TreeSet treeSet = new TreeSet(comparator);
 
   //3.向 TreeSet 中添加 步驟 1 中 compare 方法中設計的類的對象
   treeSet.add(new NewBookBean("A",34));
   treeSet.add(new NewBookBean("S",1));
   treeSet.add( new NewBookBean("V",46));
   treeSet.add( new NewBookBean("Q",26));

其實可以看到,Comparator 的使用是一種策略模式,不熟悉策略模式的同學可以點這里查看: 策略模式:網絡小說的固定套路 了解。

排序類中持有一個 Comparator 接口的引用:

Comparator<? super K> comparator;
而我們可以傳入各種自定義排序規則的 Comparator 實現類,對同樣的類制定不同的排序策略。

總結

Java 中的兩種排序方式:

Comparable 自然排序。(實體類實現)
Comparator 是定制排序。(無法修改實體類時,直接在調用方創建)

同時存在時采用 Comparator(定制排序)的規則進行比較。

對于一些普通的數據類型(比如 String, Integer, Double…),它們默認實現了Comparable 接口,實現了 compareTo 方法,我們可以直接使用。

而對于一些自定義類,它們可能在不同情況下需要實現不同的比較策略,我們可以新創建 Comparator 接口,然后使用特定的 Comparator 實現進行比較。

這就是 Comparable 和 Comparator 的區別。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

原文鏈接:http://blog.csdn.net/u011240877/article/details/53399019

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产午夜精品福利 | 日本公与妇中文在线 | 日本xxxⅹ69xxxx护士 | 猛男深夜狂cao小男生 | 日韩欧美一区二区三区免费看 | 韩国漂亮美女三级在线观看 | 青青久久精品国产免费看 | 日本片免费观看一区二区 | 丝袜护士强制脚足取精 | 四虎永久免费地址 | 欧美坐爱 | 国产网站视频 | 青青青青青国产免费手机看视频 | 国产免费丝袜调教视频 | 15同性同志18 | 国产一久久香蕉国产线看观看 | hd在线观看免费高清视频 | t66y地址一地址二地址三 | 无人影院免费观看 | 亚洲AV蜜桃永久无码精品红樱桃 | 天天综合色天天综合网 | 亚洲国产一区二区三区青草影视 | 明星ai人脸替换造梦在线播放 | 99视频网址| 俄罗斯图书馆无打码久久 | 九九99亚洲精品久久久久 | 国产福利在线观看91精品 | 亚洲小视频在线 | 亚洲欧美日韩中文高清一 | 国产精品第一区揄拍 | 蹭蹭妈妈的朋友小说 | 手机在线观看网站免费视频 | 91天堂素人 | 日本中文字幕一区二区高清在线 | 亚洲黄网站wwwwww | 京东热dj6666| 日本69av | 朝鲜美女免费一级毛片 | 日本三级免费看 | 暖暖的免费观看高清视频韩国 | 美国69xxxx59 |