【Java基礎】通用程式設計

cryAllen發表於2016-06-28

Num1:for-each迴圈優先於傳統的for迴圈

java1.5版本釋出之前的做法:

for(int i=0;i<a.length;i++){
  doSomething(a[i]);
}

java1.5發行版本中引入的for-each迴圈,通過完全隱藏迭代器或索引變數,避免了混亂和出錯的可能。

示例程式碼:

enum Suit {
    CLUB, DIAMOND, HEART, SPADE
}

enum Rank {
    ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING
}

class Card {
    final Suit suit;
    final Rank rank;

    Card(Suit suit, Rank rank) {
        this.suit = suit;
        this.rank = rank;
    }
}

public class NestedIteration {
    public static void main(String[] args) {
        Collection<Suit> suits = Arrays.asList(Suit.values());
        Collection<Rank> ranks = Arrays.asList(Rank.values());

        List<Card> deck = new ArrayList<Card>();
        for (Iterator<Suit> i = suits.iterator(); i.hasNext();)
            for (Iterator<Rank> j = ranks.iterator(); j.hasNext();)
                deck.add(new Card(i.next(), j.next()));

        // Preferred idiom for nested iteration on collections and arrays
        // for (Suit suit : suits)
        // for (Rank rank : ranks)
        // deck.add(new Card(suit, rank));
    }
}

總之,for-each迴圈在簡潔性和預防Bug方面有著傳統的for迴圈無法比擬的優勢,並且沒有效能損失。應該儘可能地使用for-each迴圈。遺憾的是,有三種常見的情況無法使用for-each迴圈:

  • 過濾:如果需要遍歷集合,並刪除選定的元素,就需要使用顯式的迭代器,以便可以呼叫它的remove方法。
  • 轉換:如果需要遍歷列表或者陣列,並取代它部分或者全部的元素值,就需要列表迭代器或者陣列索引,以便設定元素的值。
  • 平行迭代:如果需要並行地遍歷多個集合,就需要顯式地控制迭代器或者索引變數,以便所有迭代器或者索引變數都可以得到同步前移。

Num2:如果需要精確的答案,請避免使用float和double

floatdouble型別尤其不適合用於貨幣計算。

Num3:基本型別優先於裝箱基本型別

自動裝箱減少了使用裝箱基本型別的繁瑣性,但是並沒有減少它的風險。

Num4:如果其他型別更適合,則儘量避免使用字串

  • 字串不適合代替其他的值型別
  • 字串不適合代替列舉型別
  • 字串不適合代替聚集型別
  • 字串也不適合代替能力表

Num5:當心字串連線的效能

字串連線操作符(+)是把多個字串合併一個字串的便利途徑。為連線n個字串而重複地使用字串連線操作符,需要n的平方級的時間。

不要使用字串連線操作符來合併多個字串,除非效能無關緊要。相反,應該使用StringBuilderappend方法。

Num6:通過介面引用物件

一般來講,應該優先使用介面而不是類來引用物件。

  • 如果有合適的介面型別存在,那麼對於引數、返回值、變數或域來說,就都應該使用介面型別進行宣告。
  • 如果沒有合適的介面存在,完全可以用類而不是介面來引用物件。

如果你養成了用介面的作為型別的習慣,你的程式將會更加靈活。

相關文章