【0】README
0.1)本文章节一(除开 Conclusion内容)转自: http://blog.csdn.net/mageshuai/article/details/3849143
0.2) 余下内容均为原创,包括源代码;
【1】Comparable与Comparator的区别(Difference)
D1)Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序:
- Comparable & Comparator 都是用来实现集合中元素的比较、排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法;
D2)Comparable 和 Comparator 位于的包不同
- Comparator位于包java.util下,而Comparable位于包 java.lang下;
D3) 一些类(String+Integer)本身就实现了Comparable, 自定义的类要加入List or Set 也要实现 Comparable接口
- D3.1) Comparable 是一个对象本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口)
- D3.2)自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,如API所说:
Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface
这里的自然顺序就是实现Comparable接口设定的排序方式。
D4)Comparator 是专用比较器,用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
- D4.1)而 Comparator 是一个专用的比较器:当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。 可以说一个是自已完成比较,一个是外部程序实现比较的差别而已。
- D4.2)比如:你想对整数采用绝对值大小来排序,Integer 是不符合要求的,你不需要去修改 Integer 类(实际上你也不能这么做)去改变它的排序行为,只要使用一个实现了 Comparator 接口的对象来实现控制它的排序就行了。
D5) Comparator定义了俩个方法:
- D5.1)分别是 int compare(T o1, T o2)和 boolean equals(Object obj),用于比较两个Comparator是否相等
true only if the specified object is also a comparator and it imposes the same ordering as this comparator.
- D5.2)有时在实现Comparator接口时,并没有实现equals方法,可程序并没有报错,原因是实现该接口的类也是Object类的子类,而Object类已经实现了equals方法
D6) Comparable接口只提供了 int compareTo(T o)方法:也就是说假如我定义了一个Person类,这个类实现了 Comparable接口;
- D6.1)那么当我实例化Person类的person1后,我想比较person1和一个现有的Person对象person2的大小时,我就可以这样来调用:
person1.comparTo(person2),通过返回值就可以判断了;
- D6.2)而此时如果你定义了一个 PersonComparator(实现了Comparator接口)的话,那你就可以这样:
PersonComparator comparator= new PersonComparator();
comparator.compare(person1,person2);
D7)Comparator 和 Comparable 定义 比较方法的不同:
- Comparator 接口定义的是 compare 方法, 而Comparable接口定义的是 compareTo 方法;
Conclusion) 当一个对象想要比较大小进行排序的时候,那么问题来了? 我们有两种方法实现(Implementation): (我心中的干货)
- I1)改变该类的结构来实现: 也即 要进行比较的对象所属类 实现 Comparable接口,重写方法 compareTo();(涉及到 Comparable.compareTo()方法)
- I2)不改变该类的结果来实现: 通过添加比较器 Comparator接口,通常的做法是 将 比较器接口 作为匿名内部类传递给 集合构造器,即可。然后在匿名内部类中重写 compare()方法; (涉及到 Comparator.compare()方法)
【2】看个荔枝:
- you can also visit https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/TreeSetTest.java
package com.corejava.chapter13;import java.util.*;import static java.lang.System.*;public class TreeSetTest
{ public static void main(String[] args){ Object obj;SortedSet<MyItem> parts = new TreeSet<>();parts.add(new MyItem("B", 1234));parts.add(new MyItem("D", 4562));parts.add(new MyItem("A", 9912));System.out.println("set sorted by part num:");System.out.println(parts);SortedSet<MyItem> set = new TreeSet<>(newComparator<MyItem>() //将比较器Comparator 作为匿名内部类传递给集Set 构造器{ public int compare(MyItem a, MyItem b){ String descrA = a.getDescription();String descrB = b.getDescription();return descrA.compareTo(descrB);}});set.addAll(parts);System.out.println("set sorted by desc :");System.out.println(set);}
}class MyItem implements Comparable<MyItem>
{private String description;private int partNumber;public MyItem(String aDescription, int aPartNumber){description = aDescription;partNumber = aPartNumber;}// ordered by partNumberpublic int compareTo(MyItem other){return Integer.compare(partNumber, other.partNumber);}public String getDescription(){return description;}public String toString(){return "[desc = " + description + ", num = " + partNumber + "]";}public boolean equals(Object otherObject){if (this == otherObject) return true;if (otherObject == null) return false;if (getClass() != otherObject.getClass()) return false;MyItem other = (MyItem) otherObject;return Objects.equals(description, other.description) && partNumber == other.partNumber;}public static void main1(String[] args){Object obj;SortedSet<String> set = new TreeSet<>();set.add("bob");set.add("car");set.add("amy");for (String str : set)out.print(str + " ");}
}