java基礎複習(抽象類和介面)
- 介面中的資料域只能是public static final,方法只能是public abstract
由於這個原因,這些修飾也可以忽略。
資料域只能是static final的原因:
stackoverflow上:
An interface can’t have behavior or state because it is intended to specify only an interaction contract, no implementation details. No behavior is enforced by not allowing method/constructor bodies or static/instance initializing blocks. No state is enforced by only allowing static final fields.Therefore, the Class can have a state (static state), but the instance state is not inferred by the interface.
- CompareTo方法和equals方法
強烈建議CompareTo應該與equals保持一致。對於兩個物件o1和o2, 應該確保以下同時成立:
o1.equals(o2)為true
o1.compareTo(o2)==0
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false
stackoverflow上有人提了一個問題,與這個有點關係,
Java, Why it is implied that objects are equal if compareTo() returns 0?
問題:
import java.util.Comparator;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
public class Person implements Comparable<Person > {
private final String name;
private int height;
public Person(String name,
int height) {
this.name = name;
this.height = height;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getName() {
return name;
}
@Override
public int compareTo(Person o) {
return Integer.compare(height, o.height);
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if (!Objects.equals(this.name, other.name)) {
return false;
}
return true;
}
public int hashCode() {
int hash = 5;
hash = 13 * hash + Objects.hashCode(this.name);
return hash;
}
public String toString() {
return "Person{" + name + ", height = " + height + '}';
}
public static class PComparator1 implements Comparator<Person> {
@Override
public int compare(Person o1,
Person o2) {
return o1.compareTo(o2);
}
}
public static class PComparator2 implements Comparator<Person> {
@Override
public int compare(Person o1,
Person o2) {
int r = Integer.compare(o1.height, o2.height);
return r == 0 ? o1.name.compareTo(o2.name) : r;
}
}
public static void test(Set<Person> ps) {
ps.add(new Person("Ann", 150));
ps.add(new Person("Jane", 150));
ps.add(new Person("John", 180));
System.out.println(ps.getClass().getName());
for (Person p : ps) {
System.out.println(" " + p);
}
}
public static void main(String[] args) {
test(new HashSet<Person>());
test(new TreeSet<Person>());
test(new TreeSet<>(new PComparator1()));
test(new TreeSet<>(new PComparator2()));
}
}
result:
java.util.HashSet
Person{Ann, height = 150}
Person{John, height = 180}
Person{Jane, height = 150}
java.util.TreeSet
Person{Ann, height = 150}
Person{John, height = 180}
java.util.TreeSet
Person{Ann, height = 150}
Person{John, height = 180}
java.util.TreeSet
Person{Ann, height = 150}
Person{Jane, height = 150}
Person{John, height = 180}
別人的解答,總結一下有下面幾點
1、首先,HashSet會根據hash code排序,
而TreeSet則是與equals、hash code沒有關係,
它只會按照class本身的compare來決定
2、第一點即解釋了問題的輸出結果
3、由上面的例子更能提醒我們,最好是使
(x.compareTo(y)==0) == (x.equals(y))
否則可能會出現一些意想不到的錯誤。