关于比较的全部
Comparator和Comparable接口
Comparable接口
Comparable is an interface for sorting. A class implement Comparable, indicates that “this class support sorting”.There is only one method in this interface: public int compareTo(T o); Suppose we use x.compareTo(y) to compare x and y: if return negative, means “x is less than y” if return 0, means “x is equal to y” if return positive, means “x is larger than y” actually “x - y”. Usually used by Collections.sort(), or Arrays.sort().
Comparator接口
Comparator is also an interface. There are two methods in this interface: int compare(T o1, T o2); // must be override boolean equals(Object obj); // not must. can inherit from Object class. For compare(x, y), return value same as compareTo(x, y). “x - y”.
Comparable是内部比较, Comparator是外部比较。
Comparable和Comparator的例子:
public class Main {
public static void main(String[] args) {
Person p1 = new Person("a", 5);
Person p2 = new Person("b", 4);
Person p3 = new Person("c", 3);
Person p4 = new Person("c", 2);
List<Person> list = new ArrayList<>(Arrays.asList(p1, p2, p3, p4));
// 默认:名字从a到z,年龄从小到大(自然顺序)
Collections.sort(list);
for(Person p : list) {
System.out.println(p.name + p.age); // [a5,b4,c2,c3]
}
// 年龄从小到大,再名字从a到z
Comparator<Person> ascAgeComparator = new Comparator<Person>(){
public int compare(Person p1, Person p2) {
return (p1.age - p2.age == 0) ?
p1.name.compareTo(p2.name) : (p1.age - p2.age);
}
};
Collections.sort(list, ascAgeComparator);
for(Person p : list) {
System.out.println(p.name + p.age); // [c2,c3,b4,a5]
}
}
private static class Person implements Comparable<Person> {
String name;
int age;
public Person(String n, int a) {
name = n;
age = a;
}
@Override
public int compareTo(Person person) {
return this.name.compareTo(person.name) == 0 ? (this.age - person.age) : this.name.compareTo(person.name);
}
}
}
用Lambda写Comparator
public class Main {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,3,2);
System.out.println("The original list: " + list); // [1,3,2]
Collections.sort(list,(e1, e2)->(e1 - e2));
System.out.println("The sorted list(e1 - e2): " + list); // [1,2,3]
Collections.sort(list,(e1, e2)->(e2 - e1));
System.out.println("The sorted list(e2 - e1): " + list); // [3,2,1]
}
}
PriorityQueue里的Comparator
原生PriorityQueue是小顶堆。
public class Main {
public static void main(String[] args) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(1);
pq.offer(5);
pq.offer(3);
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println("");
// 1,3,5
pq = new PriorityQueue<>((a, b) -> (a - b));
pq.offer(1);
pq.offer(2);
pq.offer(3);
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println("");
// 1,2,3
pq = new PriorityQueue<>((a, b) -> (b - a));
pq.offer(1);
pq.offer(2);
pq.offer(3);
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
// 3,2,1
}
}
关于重写equals()方法:
当我们要用equals来比较自己class时,(使用hashmap也会用到),需要重写equals()方法。三步:
- 检查不等于null
- 检查instanceof
- 强制类型转换之后,检查properties。
重写equals()方法必须重写hashcode()方法,return一个无关紧要的,但对每个instance都不同的数即可。一般是用一个质数去乘一个property。
- equals 是 hashcode的充分不必要条件 两个不同的object可以有一样的hashcode
- 如果equals为true,hashcode必须返回相同的值
- == 比较内存里的物理地址。
private class myKey {
int i;
int j;
MyKey(int i, int j) {
this.i = i;
this.j = j;
}
@Override
public boolean equals(Object that) {
return that != null
&& that instanceof MyKey
&& ((MyKey)that).i == i
&& ((MyKey)that).j == j;
}
@Override
public int hashCode() {
return 31 * i * j;
}
}