茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1671823 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
HoneyMoon_Day1_00044.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

爪哇咖啡屋 : [轉貼]神奇的 foreach

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]神奇的 foreach

神奇的 foreach



public void go(int[] arr) {
    for(int i = 0; i < arr.length; i++) {
        System.out.println(arr[i]);
    }
}

事實上很多時候,從頭到尾走訪一個陣列(或Collection)中所有元素,是很常見的需求,上面的寫法並沒有錯,只不過索引資訊基本上是不需要的,硬要寫是很冗長的事。

在J2SE 5.0之後,引進了foreach新語法,上例你可以這麼改寫:
public void go(int[] arr) {
    for(int element : arr) {
        System.out.println(element);
    }
}

這個語法其實不僅限於陣列,還可以用在List、Set等。例如若是List實作物件,可以這麼寫:
public void go(List<String> list) {
    for(String element : list) {
        System.out.println(element);
    }
}


如果 是Set也是可以的,例如:
public void go(Set<String> set) {
    for(String element : set) {
        System.out.println(element);
    }
}

事實上,只要是Collection介面的實作物件,都可以用foreach語法:
public void go(Collection<String> collection) {
    for(String element : collection) {
        System.out.println(element);
    }
}

Java的foreach語法,其實是編譯器給的語法蜜糖。如果foreach要走訪的是陣列,事實上,編譯器會自動展開為以下的程式碼:
public void go(int ai[]) {
    int ai1[] = ai;
    int i = ai1.length;

    for(int j = 0; j < i; j++) {
        int k = ai1[j];
        System.out.println(k);
    }
}

若foreach運用在Collection的實作物件上,其實編譯器會展開為:
public void go(Collection collection) {
    String s;
    for(Iterator iterator = collection.iterator();
        iterator.hasNext(); System.out.println(s))
        s = (String)iterator.next();
}

無論是Collection、List或Set,展開後皆利用iterator()方法傳回Iterator物件,並利用Iterator來移動、傳回下一個物件,這是 Iterator 模式 的實現。


在J2SE 1.4之前,Collection介面上直接定義了iterator()方法必須實作,因此所有Collection實作物件,皆需實作iterator ()。在J2SE 5.0之後,引進了Iterable介面,在介面中定義了iterator()方法,該方法必須傳回Iterator物件,而Collection介面繼 承了Iterable介面,因此所有Collection實作物件,皆需實作iterator(),因此所有Collection實作物件,都可以搭配使用foreach語法。

然而並非只有Collection介面的實作物件,才可以搭配foreach語法,事實上,由於Iterable介面的引進,使得只要是實作Iterable介面的物件,皆可搭配foreach語法來使用。例如:
public void go(Iterable<String> iterable) {
    for(String element : iterable) {
        System.out.println(element);
    }
}

不管你是List、Set還是Collection,只要是Iterable的物件,都可以用這個go,或是直接用foreach語法,像是:
  • Some.java

import java.util.Iterator;

public class IterableString >implements Iterable<Character> {
private String original;

public IterableString(String original) {
this.original = original;
}

public Iterator<Character> iterator() {
return >new InnerIterator();
}

>private class InnerIterator implements Iterator<Character> {
>public boolean hasNext() {
>return index < original.length();
>public Character next() {
>Character c = original.charAt(index);
>return c;
>public void remove() {>}
>}
}


IterableString類別實作了Iterable介面,因此你可以像以下這麼搭配foreach:
  • Main.java
     for(Character c : str) {
System.out.println(c);
}
}
}

若你反組譯程式,會發現編譯器作了這些事:
Character c;
for(Iterator iterator = str.iterator(); iterator.hasNext();
  System.out.println(c))
    c = (Character)iterator.next();

在JDK7之後,有不少API都實作了Iterable,例如NIO2的Path物件等。

原文出處: 神奇的 foreach
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Java8 新特性之 forEach + Lambda 表達式遍歷 Map 和 List

Java8新特性之forEach+Lambda 表達式遍歷Map和List

2017年04月20日 12:18:32

這是Java8系列的第二篇,今天來說一下Java8中forEach的簡單使用。我們使用對比的方式來看應該會看得更加清楚,更能理解:
一、遍歷Map


============Java8之前的方式==========
Map<String, Integer> items = new HashMap<>();
items;
items;
items;
items;
items;
items;
for (Map.entrySet()) {
System;
}
============forEach + Lambda表達式==========
Map<String, Integer> items = new HashMap<>();
items;
items;
items;
items;
items;
items;
items;
items.forEach((k,v)->{
System;
if(.equals(k)){
System;
}
});

二遍歷List:
============Java8之前的方式==========


;
items;
items;
items;
items;
items;
for(String item : items){
System;
}
============forEach + Lambda表達式==========
List<String> items = new ArrayList<>();
items;
items;
items;
items;
items;
//輸出:A,B,C,D,E
items;
//輸出 : C
items.forEach(item->{
if(.equals(item)){
System;
}
});

引入forEach + Lambda表達式之後,代碼量確實減少了很多。


原文出處: Java8新特性之forEach+Lambda 表达式遍历Map和List - Scnu_wang的博客 - CSDN博客
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Java 8 Lambda Collection forEach() 用法

Java 8 Lambda Collection forEach() 用法

Java 8 Collection forEach()用法如下。


public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("matt","john","gary");
// 使用for loop
for(int i = 0 ; i < list.size() ; i++ ) {
System.out.println(list.get(i));
}
// 使用for-each loop
for(String s : list) {
System.out.println(s);
}
// 使用Java 8 forEach()
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
// 使用Java 8 forEach() 搭配 Lambda語法
list.forEach(s -> System.out.println(s));
// 使用Java 8 forEach() 搭配 Lambda 及 Method References語法
list.forEach(System.out::println);
}
}

上面範例中每個loop的結果都相同。

在Java 8的 Iterable介面新增了 forEach()方法,接收的參數為 Consumer介面的實作,而 Consumer是只有一個抽象方法( accept())的 Functional Interface,所以可以用 Lambda語法改寫。



原文出處:菜鳥工程師 肉豬: Java 8 Lambda Collection forEach() 用法
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|