Background
There are two methods to implement sorting for Custom Class in Java.
-
Comparable< T >
-
It is an interface
-
< T > - the type of objects that this object may be compared to
-
It has only method:
int compareTo(T o) { "do something" }
-
-
Comparator< T >
-
It is an interface
-
< T > - the type of objects that may be compared by this comparator
-
We usually use one method
int compare(T o1, T o2) { "do something" }
-
Why Use It?
-
我们需要对自定义的类排序时,但是Java内部没有实现这样的接口
-
比如我们自定义一个类叫Dog, 要求根据dog的年龄进行排序
-
public class Dog { String name; int age; public Dog(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
-
Output 会报错:
public class Main { public static void main(String[] args) { Dog[] dogs = {new Dog("David", 3), new Dog("Bill", 1)}; Arrays.sort(dogs); System.out.println(Arrays.toString(dogs)); } } /* Exception in thread "main" java.lang.ClassCastException: com.algoxi.my_error.comparable.Dog cannot be cast to java.lang.Comparable at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320) at java.util.ComparableTimSort.sort(ComparableTimSort.java:188) at java.util.Arrays.sort(Arrays.java:1246) at com.algoxi.Main.main(Main.java:12) */
How To Use It?
-
用comparable
- Dog类直接实现 comparable
- Dog类里面也要实现compareTo的方法
public class Dog implements Comparable<Dog> { String name; int age; public Dog(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Dog o) { if (this.age == o.age) { return 0; } return this.age < o.age ? -1 : 1; } }
- Output:
public class Main { public static void main(String[] args) { Dog[] dogs = {new Dog("David", 3), new Dog("Bill", 1)}; Arrays.sort(dogs); System.out.println(Arrays.toString(dogs)); } } /* [Dog{name='Bill', age=1}, Dog{name='David', age=3}] */
-
用Comparator
- 原来的Dog保持不变
public class Dog { String name; int age; public Dog(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
- 创建一个DogComparator类
import java.util.Comparator; public class DogComparator implements Comparator<Dog> { @Override public int compare(Dog o1, Dog o2) { if (o1.age == o2.age) { return 0; } return o1.age < o2.age ? -1 : 1; } }
- Output:
- 要对comparator进行new的操作
public class Main { public static void main(String[] args) { Dog[] dogs = {new Dog("David", 3), new Dog("Bill", 1)}; Arrays.sort(dogs, new DogComparator()); System.out.println(Arrays.toString(dogs)); } } /* [Dog{name='Bill', age=1}, Dog{name='David', age=3}] */
Anonymous Inner Class
-
Anonymous Example
-
PriorityQueue<Dog> minHeap = new PriorityQueue<>(new Comparator<Dog>() { @Override public int compare(Dog o1, Dog o2) { if (o1.age == o2.age) { return 0; } return o1.age < o2.age ? -1 : 1; } });
-
Normal Example
-
PriorityQueue<Dog> minHeap = new PriorityQueue<>(new DogComparator());
-
public class DogComparator implements Comparator<Dog> { @Override public int compare(Dog o1, Dog o2) { if (o1.age == o2.age) { return 0; } return o1.age < o2.age ? -1 : 1; } }
-
Another Tips:
- We can use Collections.reverseOrder() in PriorityQueue’s constructor to implement maxHeap.
“==” and equals
-
For Object
-
check value: o1.equals(o2)
-
check address: o1 == o2
-
public static void main(String[] args) { String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1 == s2); // false System.out.println(s1.equals(s2)); //true }
- because constant pool, they are created in same address
-
public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); // true System.out.println(s1.equals(s2)); //true }
-
-
For Primitive Type
- check value: i1 == i2
end.