Effective Java Item46 – For-each 優先於傳統的for或while

這篇是Effective Java – Prefer for-each loops to traditional for loops章節的讀書筆記 本篇的程式碼來自於原書內容

Item46: For-each 優先於傳統的for或while

Java 1.5版本之前 要loop一個collection 大家這樣做

for (Iterator i = c.iterator(); i.hasNext(); ) {
  doSomething((Element) i.next()); // (No generics before 1.5)
}

loop數組則是這樣

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

這些做法已經比while都好了 但還是太多地方你可能變動到你的索引變量 或是迭代器

所以本書推薦的方式如下

for (Element e : elements) {
  doSomething(e);
}

冒號代表 對於集合中的每個元素e

不但性能方面一樣(甚至更好) 也不會讓你有機會寫出bug

作者還給出了一個例子 想印出一副牌的每一張

enum Suit { CLUB, DIAMOND, HEART, SPADE }
enum Rank { ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT,
NINE, TEN, JACK, QUEEN, KING }
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()));
  }
}

原因也很簡單 就是兩個迭代器一起動了 解法是要先暫存外部的那個值

Effective Java Item46 - For-each 優先於傳統的for或while

長得實在醜 又很容易有bug 如果是用for-each的話

for (Suit suit : suits){
  for (Rank rank : ranks){
    deck.add(new Card(suit, rank));
  }
}

簡直就是優雅

Iterable

那對於什麼樣的類別可以用for-each呢 答案是那個類別必須要實作Iterable

public interface Iterable<E> {
  //Returns an iterator over the elements in this iterable
  Iterator<E> iterator()
}

例外

基本上 只要你要循環的這個類別有實作Iterable 你就應該用for-each

1.性能一樣

2.預防bug

3.程式簡潔

但有三種情況無法使用for-each 只能乖乖的用for

1.過濾或刪除: 要刪東西的話 就必須用迭代器(因為你可能需要呼叫到remove())

2.轉換: 就是改變值 for-each只能用來讀取元素

3.平行迭代: 就是剛剛的bug變成feature的時候 當你真的想要內外兩層的迴圈的索引或迭代器一起前進

原文 

https://jyt0532.github.io/2018/04/14/prefer-for-each-loops-to-traditional-for-loops/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Effective Java Item46 – For-each 優先於傳統的for或while

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址