關於《effectivity Java》閱讀筆記 01

關於《effectivity Java》閱讀筆記

第八章 – 通用的程序設計


關於局部變量的初始化

  • 將局部變量最小化,可以增加代碼的可讀性和可維護性,並降低出錯的可能性。

  • 要使局部變量的作用域最小化,最好的做法就是在第一次使用它的時候進行聲明。
    如果變量在使用之前聲明,會影響影響試圖理解代碼的讀者,分散他們的注意力。耗費時間尋找變量聲明的地方。

  • 幾乎每個局部變量都應該包含一個初始化表達式,如果一個變量被一個方法初始化,而這個方法可能會拋出一個受檢的異常,該變量就必須在try快內部進行初始化。


for循環的優劣

根據循環中循環變量的作用域和數目進行評價,因此 for循環優於while循環,foreach優於傳統for。

下面是遍歷的首先做法:

//適用與集合和數組
for(Element e: c){
    doSomething(e);
}

在java 1.5版本之前的首先做法如下:

// 遍歷集合
for(Iterator i = c.iterator(); i.hasNext();){
    doSomething((Element) i.next());
}
// 遍歷數組
for(int i = 0; i<a.length; i++){
    doSomething(a[i]);
}

下面是另一種局部變量作用域最小化的循環做法:

// expensiveComputation()方法用於獲取n的數量,這樣做 局部變量i,n作用域只在for循環內。
for(int i = 0, n = expensiveComputation(); i <n ; i++){
    doSomething(i);
}

有三種情況無法使用for-each循環

  • 1.過濾 —- 如果需要遍歷集合,並刪除選定的元素,就需要使用顯示的迭代器,以便可以調用它的remove方法
  • 2.轉換 —- 如果需要遍歷列表或者數組,並替換它全部或者部分元素值,就需要列表迭代或者數組索引,以便設定元素的值
  • 3.平行迭代 —- 如果需要並行的遍歷多個集合,就需要顯示的控制迭代器或者索引變量,以便所有的迭代器或者索引變量都可以得到同步前移。

第49條:基本類型優於裝箱基本類型

java 1.5版本增加了自動裝箱和自動拆箱,他們之間主要有三個區別:

  • 基本類型只有值,裝箱基本類型則具有與他們的值不同的同一性,換句話說,倆個裝箱基本類型可以具有相同的值和不同的同一性。
  • 基本類型只有功能完備的值,而每個裝箱基本類型除了他對應基本類型的所有功能值以外,還有一個非功能值: null。
  • 基本類型通常比裝箱基本類型更節省時間和空間。

考慮下面這個程序有什麼問題:

public static void main(String[] args){
    Long sun = 0L;
    for(long i = 0; i<100; i++){
        sum += i;
    }
    System.out.println(sum);
}

這段代碼運行起來要比預想的慢很多,因爲它不小心把局部變量sum聲明爲裝箱基本類型Long。而不是基本類型long,這樣程序編譯起來沒有錯誤或者警告,變量被反覆的裝箱和拆箱,導致明顯的性能下降。


字符串的使用

如果其他類型更適合,要儘量避免使用字符串,字符串經常被錯誤的用來替代基本類型、枚舉類型、聚集類型。

字符串連接操作符( + )適用於: 產生單獨的一行輸出,或者構造一個字符串來表示一個較小的、大小固定的對象。但是如果是連接n個字符串,頻繁的使用字符串連接符,需要n的平方級的時間。這是因爲字符串不可變,當倆個字符串連接在一起時,他們的內容都要被拷貝。


考慮下面這段代碼:

public String statement(){
    String result = "";
    for(int i=0; i< numItems(); i++){
        result += lineForItem(i); //String concatenation 
    }
    return result;
}

如果項目數量巨大,這個方法的時間就難以估算。爲了獲得可以接受的性能,請使用StringBuilder代替String。(Java 1.5發行版本中增加了非同步StringBuilder類,代替現在過時的StringBuffer類)。

public String statement(){
    StringBuilder b = new StringBuilder(numItems()*LINE_WIDTH);
    for(int i = 0;i<numItems();i++){
        b.append(lineForItem(i));
    }
    return b.toString();
}

第二種做法比第一張大約快85倍左右。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章