Effective Java 第二版 中文版 筆記(8-12)避免使用終結方法
我對此部分沒有什麼興趣,因為誰會閒的沒事覆蓋java自身的方法。
八、覆蓋equals ;
這裡最重要的就是遵守約定;
- 自反性(reflexive)—>
x != null && x.equals(x) == true
- 對稱性(symmetric)—>
if(x != null && x.equals(y))
可以推出y.equals(x)
- 傳遞性(transitive)—>
x != null && x.equals(y) == true && y.equals(z)
可以推出x.equals(z)
- 一致性(consistent)—>對於非null的x、y,只要equals的比較操作在物件中所用的資訊沒有被修改,多次呼叫equals返回的一致是true或者一致是false
- 對於非null的x,
x.equals(null)
返回值一定是false
九、覆蓋equels 的時候總要覆蓋hashcode
1.hashCode的規範
a.應用程式執行的時候,如果equals方法的比較操作所用到的資訊沒有被修改,那麼對於這個物件的多次呼叫,hashCode的值應該是不變的。
b.如果物件的equals相等,hashCode也必須相等
c.如果物件的equals不相等,hashCode可以相等,也可以不相等,但不等最好,這樣可以提高散列表的效能。(對散列表的知識,我後面的文章會詳細講解)。
Object類的hashCode方法 public native int hashCode(); Integer類的hashCode方法 public int hashCode() { return value; } String類的hashCode方法 public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; } Boolean類的hashCode方法 public static int hashCode(boolean value) { return value ? 1231 : 1237;
十、始終要覆蓋toString
目的:使我們清楚的看到相應的資訊
雖然Object提供了toString的實現,但它返回的是類名[email protected]+雜湊碼,這不是我們想看到的,所以強烈建議重寫toString方法,把它展示成我們想要的結果。
十一、謹慎的覆蓋clone
一個類要想實現克隆,需要實現Cloneable介面,表明這個類的物件具有克隆的功能。
首先應該明確通過一個物件克隆出另一個物件的概念:通過一個物件克隆出另一個物件,簡稱物件1和物件2,這兩個物件就成為兩個獨立的物件,
那麼對物件1做任何的修改,物件2應該不受影響;對物件2做任何的修改的,物件1就不應該受影響。這樣就要求物件1與物件2的例項域各自是獨立的。
那麼我們知道一個物件的例項域,包括基本型別(int,long..等等)的域,引用型別的域(分為可變的域和final不可變的域)。
十二、考慮實現Comparable
實現了Comparable介面的類,它的例項就具備了排序功能。
然後,把實現了Comparable介面的類的例項,新增到List或者array集合中,呼叫Collections.sort或者Arrays.sort就可以得到一個排好序的集合。
一個類實現Comparable介面時,要遵守如下約定:
1.將當前物件與指定物件進行比較。當該物件小於、等於、或大於指定物件的時候,分別返回一個負整數(-1)、零或者正整數(1)。如果由於指定物件的型別而無法與該物件進行比較,則丟擲ClassCastException異常。
程式碼:
public class Employee implements Comparable<Employee> {
private int EmpID ;
private String Ename;
private double Sal ;
private static int i;
public Employee() {
EmpID = i++;
Ename = "dont know";
Sal = 0.0;
}
public Employee(String ename, double sal) {
EmpID = i++;
Ename = ename;
Sal = sal;
}
public String toString() {
return "EmpID " + EmpID + "\n" + "Ename " + Ename + "\n" + "Sal " + Sal ;
}
public int compareTo(Employee arg0) {
// TODO Auto-generated method stub
if (Sal < arg0. Sal)
return -1;
else if (Sal == arg0.Sal)
return 0;
else
return 1;
}
}
public class ComparableDemo {
public static void main(String[] args) {
List<Employee> ts1 = new ArrayList<Employee>();
ts1.add(new Employee( "Tom", 40000.00));
ts1.add(new Employee( "Harry", 20000.00));
ts1.add(new Employee( "Maggie", 50000.00));
ts1.add(new Employee( "Chris", 70000.00));
Collections.sort(ts1);
Iterator<Employee> itr = ts1.iterator();
System.out.println( "------List--------");
while (itr.hasNext()) {
Object element = itr.next();
System. out.println(element + "\n" );
}
System.out.println( "-----Array--------");
Employee[] oneArray =
{ new Employee("Peter" , 30000.00), new Employee( "Harry", 20000.00),
new Employee("Maggie" , 50000.00)};
Arrays.sort(oneArray);
for (Employee one : oneArray) {
System. out.println(one + "\n" );
}
}
}