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

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

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java 中Comparable與Comparator詳解與比較

java 中Comparable與Comparator詳解與比較

2020-09-08 10:39Java之家 Java教程

這篇文章主要介紹了java 中Comparable與Comparator詳解與比較的相關資料,需要的朋友可以參考下

javaComparableComparator詳解

今天查看TreeMap的源碼,發現其鍵必須是實現Comparable或者Comparator的接口時產生了一些興趣,比如在TreeMap中的put方法分別對Comparable和Comparator接口分別進行處理。那么疑問就來了,Comparable和Comparator接口的區別是什么,Java中為什么會存在兩個類似的接口?

  Comparable和Comparator接口都是用來比較大小的,首先來看一下Comparable的定義:

?
1
2
3
4
5
package java.lang;
import java.util.*;
public interface Comparable<T> {
  public int compareTo(T o);
}

  Comparator的定義如下:

?
1
2
3
4
5
package java.util;
public interface Comparator<T> {
  int compare(T o1, T o2);
  boolean equals(Object obj);
}

  Comparable對實現它的每個類的對象進行整體排序。這個接口需要類本身去實現(這句話沒看懂?沒關系,接下來看個例子就明白了)。若一個類實現了Comparable 接口,實現 Comparable 接口的類的對象的 List 列表 ( 或數組)可以通過 Collections.sort(或 Arrays.sort)進行排序。此外,實現 Comparable 接口的類的對象 可以用作 “有序映射 ( 如 TreeMap)” 中的鍵或 “有序集合 (TreeSet)” 中的元素,而不需要指定比較器。

  舉例(類Person1實現了Comparable接口)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package collections;
 
public class Person1 implements Comparable<Person1>
{
  private int age;
  private String name;
 
  public Person1(String name, int age)
  {
    this.name = name;
    this.age = age;
  }
  @Override
  public int compareTo(Person1 o)
  {
    return this.age-o.age;
  }
  @Override
  public String toString()
  {
    return name+":"+age;
  }
}

  可以看到Person1實現了Comparable接口中的compareTo方法。實現Comparable接口必須修改自身的類,即在自身類中實現接口中相應的方法。

  測試代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
Person1 person1 = new Person1("zzh",18);
   Person1 person2 = new Person1("jj",17);
   Person1 person3 = new Person1("qq",19);
 
   List<Person1> list = new ArrayList<>();
   list.add(person1);
   list.add(person2);
   list.add(person3);
 
   System.out.println(list);
   Collections.sort(list);
   System.out.println(list);

  輸出結果:

?
1
2
[zzh:18, jj:17, qq:19]
[jj:17, zzh:18, qq:19]

  如果我們的這個類無法修改,譬如String,我們又要對其進行排序,當然String中已經實現了Comparable接口,如果單純的用String舉例就不太形象。對類自身無法修改這就用到了Comparator這個接口(策略模式)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public final class Person2
{
  private int age;
  private String name;
 
  public Person2(String name, int age)
  {
    this.name = name;
    this.age = age;
  }
 
  @Override
  public String toString()
  {
    return name+":"+age;
  }
 
  //getter and setter方法省略....
}

  如類Person2,這個類已經固定,無法進行對其類自身的修改,也修飾詞final了,你也別想繼承再implements Comparable,那么此時怎么辦呢?在類的外部使用Comparator的接口。如下測試代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Person2 p1 = new Person2("zzh",18);
   Person2 p2 = new Person2("jj",17);
   Person2 p3 = new Person2("qq",19);
   List<Person2> list2 = new ArrayList<Person2>();
   list2.add(p1);
   list2.add(p2);
   list2.add(p3);
   System.out.println(list2);
   Collections.sort(list2,new Comparator<Person2>(){
 
     @Override
     public int compare(Person2 o1, Person2 o2)
     {
       if(o1 == null || o2 == null)
         return 0;
       return o1.getAge()-o2.getAge();
     }
 
   });
   System.out.println(list2);

  輸出結果:

?
1
2
[zzh:18, jj:17, qq:19]
[jj:17, zzh:18, qq:19]

  這里(public static <T> void sort(List<T> list, Comparator<? super T> c) )采用了內部類的實現方式,實現compare方法,對類Person2的list進行排序。

  再譬如博主遇到的真實案例中,需要對String進行排序,且不區分大小寫,我們知道String中的排序是字典排序,譬如:A a D排序之后為A D a,這樣顯然不對,那么該怎么辦呢?同上(下面代碼中的list是一個String的List集合):

?
1
2
3
4
5
6
7
8
9
10
Collections.sort(list, new Comparator<String>()
   {
     @Override
     public int compare(String o1, String o2)
     {
       if(o1 == null || o2 == null)
         return 0;
       return o1.toUpperCase().compareTo(o2.toUpperCase());
     }
   });

  這樣就可以實現不區分大小進行排序String的集合了,是不是很方便~

  細心的同學可能會有疑問,明明在Comparator接口中定義了兩個方法,為什么繼承的時候只實現了一個方法,難道要顛覆我對Java接口常識的理解了嚒?

  實際上,我們知道當一個類沒有顯式繼承父類的時候,會有一個默認的父類,即java.lang.Object,在Object類中有一個方法即為equals方法,所以這里并不強制要求實現Comparator接口的類要實現equals方法,直接調用父類的即可,雖然你顯式的實現了equals()方法 will be a better choice~

  在《Effective Java》一書中,作者Joshua Bloch推薦大家在編寫自定義類的時候盡可能的考慮實現一下Comparable接口,一旦實現了Comparable接口,它就可以跟許多泛型算法以及依賴于改接口的集合實現進行協作。你付出很小的努力就可以獲得非常強大的功能。

  事實上,Java平臺類庫中的所有值類都實現了Comparable接口。如果你正在編寫一個值類,它具有非常明顯的內在排序關系,比如按字母順序、按數值順序或者按年代順序,那你就應該堅決考慮實現這個接口。

  compareTo方法不但允許進行簡單的等同性進行比較,而且語序執行順序比較,除此之外,它與Object的equals方法具有相似的特征,它還是一個泛型。類實現了Comparable接口,就表明它的實例具有內在的排序關系,為實現Comparable接口的對象數組進行排序就這么簡單: Arrays.sort(a);

  對存儲在集合中的Comparable對象進行搜索、計算極限值以及自動維護也同樣簡單。列如,下面的程序依賴于String實現了Comparable接口,它去掉了命令行參數列表中的重復參數,并按字母順序打印出來:

?
1
2
3
4
5
6
7
public class WordList{
  public static void main(String args[]){
    Set<String> s = new TreeSet<String>();
    Collections.addAll(s,args);
    System.out.println(s);
  }
}

  Comparable 是排序接口;若一個類實現了 Comparable 接口,就意味著 “該類支持排序”。而 Comparator 是比較器;我們若需要控制某個類的次序,可以建立一個 “該類的比較器” 來進行排序。

  前者應該比較固定,和一個具體類相綁定,而后者比較靈活,它可以被用于各個需要比較功能的類使用。可以說前者屬于 “靜態綁定”,而后者可以 “動態綁定”。

  我們不難發現:Comparable 相當于 “內部比較器”,而 Comparator 相當于 “外部比較器”。

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品nv在线观看 | 深夜在线观看网站 | 娇妻被又大又粗又长又硬好爽 | 18美女光胸光屁屁洗澡 | 特黄未满14周岁毛片 | 欧美综合色网 | 我与恶魔的h生活ova | 国产微拍精品一区 | 2021国产麻豆剧传媒剧情最新 | 日本精品久久久久久久久免费 | 荡娃艳妇有声小说 | 77色视频在线 | 四虎精品成人a在线观看 | 男男视频18免费网站 | 亚洲人成网站在线观看90影院 | 欧美人禽杂交av片 | 91尤物在线视频 | 亚洲AV无码乱码国产麻豆穿越 | 四虎免费在线观看视频 | 国产在视频线精品视频 | 古装一级无遮挡毛片免费观看 | sese在线播放| 能播放的欧美同性videos | 99久久精品免费看国产四区 | 双性np玩烂了np欲之国的太子 | 青青草伊人久久 | 国产精品成人免费观看 | 欧美一区精品二区三区 | 国产精品区一区二区免费 | 美女黄板视频 | 精品综合在线 | 男人把j放进女人的p里视频 | 秋霞鲁丝影院久久人人综合 | 亚洲第一天堂无码专区 | 五月天国产视频 | 污小说在线阅读 | 久久这里只有精品国产精品99 | 亚洲国产美女精品久久久久 | 久久精品99国产精品日本 | 波多野结衣 在线 | 久久婷婷五月综合色丁香 |