国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 對(duì)比Java中的Comparable排序接口和Comparator比較器接口

對(duì)比Java中的Comparable排序接口和Comparator比較器接口

2020-05-05 14:31kuiwu-wang JAVA教程

Comparable和Comparator接口都可用作普通意義上對(duì)象間的比大小,但兩個(gè)接口在實(shí)例化方面的用法不盡相同,接下來(lái)我們就來(lái)詳細(xì)對(duì)比Java中的Comparable排序接口和Comparator比較器接口

Comparable
Comparable 是排序接口。
若一個(gè)類(lèi)實(shí)現(xiàn)了Comparable接口,就意味著“該類(lèi)支持排序”。 即然實(shí)現(xiàn)Comparable接口的類(lèi)支持排序,假設(shè)現(xiàn)在存在“實(shí)現(xiàn)Comparable接口的類(lèi)的對(duì)象的List列表(或數(shù)組)”,則該List列表(或數(shù)組)可以通過(guò) Collections.sort(或 Arrays.sort)進(jìn)行排序。
此外,“實(shí)現(xiàn)Comparable接口的類(lèi)的對(duì)象”可以用作“有序映射(如TreeMap)”中的鍵或“有序集合(TreeSet)”中的元素,而不需要指定比較器。
Comparable 接口僅僅只包括一個(gè)函數(shù),它的定義如下:

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

說(shuō)明: 假設(shè)我們通過(guò) x.compareTo(y) 來(lái)“比較x和y的大小”。若返回“負(fù)數(shù)”,意味著“x比y小”;返回“零”,意味著“x等于y”;返回“正數(shù)”,意味著“x大于y”。
Comparable 接口已經(jīng)泛型化了,所以實(shí)現(xiàn) Comparable 的對(duì)象聲明它可以與什么類(lèi)型進(jìn)行比較。(通常,這是對(duì)象本身的類(lèi)型,但是有時(shí)也可能是父類(lèi)。)
public interface Comparable { public boolean compareTo(T other); }
所以 Comparable 接口包含一個(gè)類(lèi)型參數(shù) T,該參數(shù)是一個(gè)實(shí)現(xiàn) Comparable 的類(lèi)可以與之比較的對(duì)象的類(lèi)型。這意味著如果定義一個(gè)實(shí)現(xiàn) Comparable 的類(lèi),比如 String,就必須不僅聲明類(lèi)支持比較,還要聲明它可與什么比較(通常是與它本身比較):
public class String implements Comparable { ... }
現(xiàn)在來(lái)考慮一個(gè)二元 max() 方法的實(shí)現(xiàn)。您想要接受兩個(gè)相同類(lèi)型的參數(shù),二者都是 Comparable,并且相互之間是 Comparable。幸運(yùn)的是,如果使用泛型方法和有限制類(lèi)型參數(shù)的話,這相當(dāng)直觀:
public static > T max(T t1, T t2) { if (t1.compareTo(t2) > 0) return t1; else return t2; }
在本例中,您定義了一個(gè)泛型方法,在類(lèi)型 T 上泛型化,您約束該類(lèi)型擴(kuò)展(實(shí)現(xiàn)) Comparable。兩個(gè)參數(shù)都必須是 T 類(lèi)型,這表示它們是相同類(lèi)型,支持比較,并且相互可比較。容易!
更好的是,編譯器將使用類(lèi)型推理來(lái)確定當(dāng)調(diào)用 max() 時(shí) T 的值表示什么意思。所以根本不用指定 T,下面的調(diào)用就能工作:

?
1
String s = max("moo", "bark");

編譯器將計(jì)算出 T 的預(yù)定值是 String,因此它將進(jìn)行編譯和類(lèi)型檢查。但是如果您試圖用不實(shí)現(xiàn) Comparable 的 類(lèi) X 的參數(shù)調(diào)用max(),那么編譯器將不允許這樣做。

Comparator
Comparator 是比較器接口。
我們?nèi)粜枰刂颇硞€(gè)類(lèi)的次序,而該類(lèi)本身不支持排序(即沒(méi)有實(shí)現(xiàn)Comparable接口);那么,我們可以建立一個(gè)“該類(lèi)的比較器”來(lái)進(jìn)行排序。這個(gè)“比較器”只需要實(shí)現(xiàn)Comparator接口即可。
也就是說(shuō),我們可以通過(guò)“實(shí)現(xiàn)Comparator類(lèi)來(lái)新建一個(gè)比較器”,然后通過(guò)該比較器對(duì)類(lèi)進(jìn)行排序。
Comparator 接口僅僅只包括兩個(gè)個(gè)函數(shù),它的定義如下:

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

說(shuō)明:
1.若一個(gè)類(lèi)要實(shí)現(xiàn)Comparator接口:它一定要實(shí)現(xiàn)compareTo(T o1, T o2) 函數(shù),但可以不實(shí)現(xiàn) equals(Object obj) 函數(shù)。
     為什么可以不實(shí)現(xiàn) equals(Object obj) 函數(shù)呢? 因?yàn)槿魏晤?lèi),默認(rèn)都是已經(jīng)實(shí)現(xiàn)了equals(Object obj)的。 Java中的一切類(lèi)都是繼承于java.lang.Object,在Object.java中實(shí)現(xiàn)了equals(Object obj)函數(shù);所以,其它所有的類(lèi)也相當(dāng)于都實(shí)現(xiàn)了該函數(shù)。
2.int compare(T o1, T o2) 是“比較o1和o2的大小”。返回“負(fù)數(shù)”,意味著“o1比o2小”;返回“零”,意味著“o1等于o2”;返回“正數(shù)”,意味著“o1大于o2”。

Comparator 和 Comparable 比較
Comparable是排序接口;若一個(gè)類(lèi)實(shí)現(xiàn)了Comparable接口,就意味著“該類(lèi)支持排序”。
而Comparator是比較器;我們?nèi)粜枰刂颇硞€(gè)類(lèi)的次序,可以建立一個(gè)“該類(lèi)的比較器”來(lái)進(jìn)行排序。
我們不難發(fā)現(xiàn):Comparable相當(dāng)于“內(nèi)部比較器”,而Comparator相當(dāng)于“外部比較器”。
我們通過(guò)一個(gè)測(cè)試程序來(lái)對(duì)這兩個(gè)接口進(jìn)行說(shuō)明。源碼如下:

?
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import java.util.*;
import java.lang.Comparable;
 
/**
 * @desc "Comparator"和“Comparable”的比較程序。
 *  (01) "Comparable"
 *  它是一個(gè)排序接口,只包含一個(gè)函數(shù)compareTo()。
 *  一個(gè)類(lèi)實(shí)現(xiàn)了Comparable接口,就意味著“該類(lèi)本身支持排序”,它可以直接通過(guò)Arrays.sort() 或 Collections.sort()進(jìn)行排序。
 *  (02) "Comparator"
 *  它是一個(gè)比較器接口,包括兩個(gè)函數(shù):compare() 和 equals()。
 *  一個(gè)類(lèi)實(shí)現(xiàn)了Comparator接口,那么它就是一個(gè)“比較器”。其它的類(lèi),可以根據(jù)該比較器去排序。
 *
 *  綜上所述:Comparable是內(nèi)部比較器,而Comparator是外部比較器。
 *  一個(gè)類(lèi)本身實(shí)現(xiàn)了Comparable比較器,就意味著它本身支持排序;若它本身沒(méi)實(shí)現(xiàn)Comparable,也可以通過(guò)外部比較器Comparator進(jìn)行排序。
 */
public class CompareComparatorAndComparableTest{
 
  public static void main(String[] args) {
    // 新建ArrayList(動(dòng)態(tài)數(shù)組)
    ArrayList<Person> list = new ArrayList<Person>();
    // 添加對(duì)象到ArrayList中
    list.add(new Person("ccc", 20));
    list.add(new Person("AAA", 30));
    list.add(new Person("bbb", 10));
    list.add(new Person("ddd", 40));
 
    // 打印list的原始序列
    System.out.printf("Original sort, list:%s\n", list);
 
    // 對(duì)list進(jìn)行排序
    // 這里會(huì)根據(jù)“Person實(shí)現(xiàn)的Comparable<String>接口”進(jìn)行排序,即會(huì)根據(jù)“name”進(jìn)行排序
    Collections.sort(list);
    System.out.printf("Name   sort, list:%s\n", list);
 
    // 通過(guò)“比較器(AscAgeComparator)”,對(duì)list進(jìn)行排序
    // AscAgeComparator的排序方式是:根據(jù)“age”的升序排序
    Collections.sort(list, new AscAgeComparator());
    System.out.printf("Asc(age) sort, list:%s\n", list);
 
    // 通過(guò)“比較器(DescAgeComparator)”,對(duì)list進(jìn)行排序
    // DescAgeComparator的排序方式是:根據(jù)“age”的降序排序
    Collections.sort(list, new DescAgeComparator());
    System.out.printf("Desc(age) sort, list:%s\n", list);
 
    // 判斷兩個(gè)person是否相等
    testEquals();
  }
 
  /**
   * @desc 測(cè)試兩個(gè)Person比較是否相等。
   *  由于Person實(shí)現(xiàn)了equals()函數(shù):若兩person的age、name都相等,則認(rèn)為這兩個(gè)person相等。
   *  所以,這里的p1和p2相等。
   *
   *  TODO:若去掉Person中的equals()函數(shù),則p1不等于p2
   */
  private static void testEquals() {
    Person p1 = new Person("eee", 100);
    Person p2 = new Person("eee", 100);
    if (p1.equals(p2)) {
      System.out.printf("%s EQUAL %s\n", p1, p2);
    } else {
      System.out.printf("%s NOT EQUAL %s\n", p1, p2);
    }
  }
 
  /**
   * @desc Person類(lèi)。
   *    Person實(shí)現(xiàn)了Comparable接口,這意味著Person本身支持排序
   */
  private static class Person implements Comparable<Person>{
    int age;
    String name;
 
    public Person(String name, int age) {
      this.name = name;
      this.age = age;
    }
 
    public String getName() {
      return name;
    }
 
    public int getAge() {
      return age;
    }
 
    public String toString() {
      return name + " - " +age;
    }
 
    /**
     * 比較兩個(gè)Person是否相等:若它們的name和age都相等,則認(rèn)為它們相等
     */
    boolean equals(Person person) {
      if (this.age == person.age && this.name == person.name)
        return true;
      return false;
    }
 
    /**
     * @desc 實(shí)現(xiàn) “Comparable<String>” 的接口,即重寫(xiě)compareTo<T t>函數(shù)。
     * 這里是通過(guò)“person的名字”進(jìn)行比較的
     */
    @Override
    public int compareTo(Person person) {
      return name.compareTo(person.name);
      //return this.name - person.name;
    }
  }
 
  /**
   * @desc AscAgeComparator比較器
   *    它是“Person的age的升序比較器”
   */
  private static class AscAgeComparator implements Comparator<Person> {
 
    @Override
    public int compare(Person p1, Person p2) {
      return p1.getAge() - p2.getAge();
    }
  }
 
  /**
   * @desc DescAgeComparator比較器
   *    它是“Person的age的升序比較器”
   */
  private static class DescAgeComparator implements Comparator<Person> {
 
    @Override
    public int compare(Person p1, Person p2) {
      return p2.getAge() - p1.getAge();
    }
  }
}

下面對(duì)這個(gè)程序進(jìn)行說(shuō)明。
1.Person類(lèi)定義。如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static class Person implements Comparable<Person>{
  int age;
  String name;
 
    ...
 
  /**
   * @desc 實(shí)現(xiàn) “Comparable<String>” 的接口,即重寫(xiě)compareTo<T t>函數(shù)。
   * 這里是通過(guò)“person的名字”進(jìn)行比較的
   */
  @Override
  public int compareTo(Person person) {
    return name.compareTo(person.name);
    //return this.name - person.name;
  
}

說(shuō)明:
(1) Person類(lèi)代表一個(gè)人,Persong類(lèi)中有兩個(gè)屬性:age(年紀(jì)) 和 name“人名”。
(2) Person類(lèi)實(shí)現(xiàn)了Comparable接口,因此它能被排序。

2.在main()中,我們創(chuàng)建了Person的List數(shù)組(list)。如下:

?
1
2
3
4
5
6
7
// 新建ArrayList(動(dòng)態(tài)數(shù)組)
ArrayList<Person> list = new ArrayList<Person>();
// 添加對(duì)象到ArrayList中
list.add(new Person("ccc", 20));
list.add(new Person("AAA", 30));
list.add(new Person("bbb", 10));
list.add(new Person("ddd", 40));

3.接著,我們打印出list的全部元素。如下:

?
1
2
// 打印list的原始序列
System.out.printf("Original sort, list:%s\n", list);

4.然后,我們通過(guò)Collections的sort()函數(shù),對(duì)list進(jìn)行排序。
由于Person實(shí)現(xiàn)了Comparable接口,因此通過(guò)sort()排序時(shí),會(huì)根據(jù)Person支持的排序方式,即 compareTo(Person person) 所定義的規(guī)則進(jìn)行排序。如下:

?
1
2
3
4
// 對(duì)list進(jìn)行排序
// 這里會(huì)根據(jù)“Person實(shí)現(xiàn)的Comparable<String>接口”進(jìn)行排序,即會(huì)根據(jù)“name”進(jìn)行排序
Collections.sort(list);
System.out.printf("Name sort, list:%s\n", list);

5.對(duì)比Comparable和Comparator
我們定義了兩個(gè)比較器 AscAgeComparator 和 DescAgeComparator,來(lái)分別對(duì)Person進(jìn)行 升序 和 降低 排序。

6.AscAgeComparator比較器
它是將Person按照age進(jìn)行升序排序。代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
/**
 * @desc AscAgeComparator比較器
 *    它是“Person的age的升序比較器”
 */
private static class AscAgeComparator implements Comparator<Person> {
 
  @Override
  public int compare(Person p1, Person p2) {
    return p1.getAge() - p2.getAge();
  }
}

7.DescAgeComparator比較器
它是將Person按照age進(jìn)行降序排序。代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
/**
 * @desc DescAgeComparator比較器
 *    它是“Person的age的升序比較器”
 */
private static class DescAgeComparator implements Comparator<Person> {
 
  @Override
  public int compare(Person p1, Person p2) {
    return p2.getAge() - p1.getAge();
  }
}

8.運(yùn)行結(jié)果 運(yùn)行程序,輸出如下:

?
1
2
3
4
5
Original sort, list:[ccc - 20, AAA - 30, bbb - 10, ddd - 40]
Name   sort, list:[AAA - 30, bbb - 10, ccc - 20, ddd - 40]
Asc(age) sort, list:[bbb - 10, ccc - 20, AAA - 30, ddd - 40]
Desc(age) sort, list:[ddd - 40, AAA - 30, ccc - 20, bbb - 10]
eee - 100 EQUAL eee - 100

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩av视屏| 欧美日韩一区二区电影 | 国产亚洲精品精品国产亚洲综合 | 日韩欧美一级 | 在线日韩欧美 | 午夜视频网站 | 精品国内 | 成人av高清 | 亚洲欧美第一页 | 亚洲精品一区二区三区 | 国产精品美女久久久久久久久久久 | 中文字幕在线视频观看 | 精品成人国产在线观看男人呻吟 | 国产免费一区二区 | 黄a视频| 天天天干天天天操 | h成人在线| 国产一区不卡 | 欧美精品在线一区二区三区 | 色在线看 | 色网站在线观看 | 在线a电影| 国产精品美女久久久久aⅴ国产馆 | 色吧综合网 | 中文日韩在线 | 国产成人在线一区二区 | 欧美一区二区三区视频 | 91精品网| 一区二区在线视频 | 免费黄色在线观看视频 | 日本一区二区三区免费观看 | 人人澡人人射 | 欧美一级片在线播放 | 亚州ava | 不卡一二区 | 久久久久久亚洲精品 | 国产精品日韩欧美 | 久久久久久久久久久久免费 | 一二三四区视频在线观看 | 亚洲精品一区二区三区在线 | 欧美亚洲综合久久 |