1. 程式人生 > >Effective Java 第二版 中文版 筆記(8-12)避免使用終結方法

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" );
    }
 
  }
}