Lambdaの遅延処理を確認してみる
櫻庭さん(@skrb)のブログJava in the Box Annex: JavaOne 2013 SF 第4日目を読んでサンプルコードを実装して処理の順序を確認してみました。
JavaSE8のバージョンはb114です。
- StreamSample.java(★1バイヤーが売り上げた合計を算出)の実行結果
実装からは「Transaction#getBuyer」「Buyer#getState(State=XX)」が最初にデータ件数分(5回)出力されて、その後「Transaction#getPrice(price=999)」が出力されると思っていましたが、遅延処理されているのでデータ件数分(5回)しかloop処理されていないことを確認。
なので終端のオペレーションであるsumを実装しない場合( ★2終端のオペレーションであるsumを除く)は、何もコンソールに出力されませんでした。(当然ですよね)
*** start sum *** Transaction#getBuyer Buyer#getState(State=NY) Transaction#getPrice(price=100) Transaction#getBuyer Buyer#getState(State=NY) Transaction#getPrice(price=200) Transaction#getBuyer Buyer#getState(State=NY) Transaction#getPrice(price=300) Transaction#getBuyer Buyer#getState(State=CA) Transaction#getBuyer Buyer#getState(State=OH) *** sum:600 ***
終端のオペレーションかどうかは、JavaDochttp://download.java.net/jdk8/docs/api/index.html?overview-summary.htmlに記載されていました。
- StreamSample.java
public class StreamSample { public static void main(String[] args) { Transaction[] trans = {new Transaction(100, new Buyer("NY"), new Person("name1")) , new Transaction(200, new Buyer("NY"), new Person("name2")) , new Transaction(300, new Buyer("NY"), new Person("name3")) , new Transaction(111, new Buyer("CA"), new Person("name4")) , new Transaction(222, new Buyer("OH"), new Person("name5")) }; List<Transaction> txns = Arrays.asList(trans); // ★1バイヤーが売り上げた合計を算出 System.out.println("*** start sum ***"); int sum = txns.stream() .filter(t -> t.getBuyer().getState().equals("NY")) .mapToInt(t -> t.getPrice()) .sum(); System.out.println(String.format("*** sum:%d ***", sum)); // ★2終端のオペレーションであるsumを除く txns.stream() .filter(t -> t.getBuyer().getState().equals("NY")) .mapToInt(t -> t.getPrice()); // セラーのみを新しいリストに作成 List<Person> sellers = txns.stream().map(Transaction::getSeller).collect(Collectors.toList()); System.out.println(String.format("*** sellers size:%d ***", sellers.size())); } }
- Transaction.java
public class Transaction { private int price; private Buyer buyer; private Person seller; public Transaction(int price, Buyer buyer, Person seller) { this.price = price; this.buyer = buyer; this.seller = seller; } public int getPrice() { System.out.println(String.format("Transaction#getPrice(price=%d)", price)); return price; } public Buyer getBuyer() { System.out.println("Transaction#getBuyer"); return buyer; } public Person getSeller() { System.out.println("Transaction#getSeller"); return seller; } }
- Buyer.java
public class Buyer { private String state; public Buyer(String state) { this.state = state; } public String getState() { System.out.println(String.format("Buyer#getState(State=%s)", state)); return state; } }
- Person.java
public class Person { private String name; public Person(String name) { this.name = name; } public String getName() { System.out.println(String.format("Person#getName(Name=%s)", name)); return name; } }
- 最後に
いつもブログを読んで、毎回本当に勉強になります!ほかにもいろいろ実装していつかJavaSE8をお仕事で使えるようになればいいな〜と思っています!