let's go developer 2011 sendai let's go java developer (programming language groovy part)

29
Java プログラミング言語 Groovy 2011528日土曜日

Upload: junji-uehara

Post on 13-Jan-2015

3.900 views

Category:

Technology


3 download

DESCRIPTION

レッツゴーデベロッパー2011発表資料、レッツゴーJavaデベロッパー「プログラミング言語Groovy編」

TRANSCRIPT

Page 1: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

Java

プログラミング言語Groovy編

2011年5月28日土曜日

Page 2: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

自己紹介上原潤二NTTソフトウェア株式会社技術評論社刊行予定「プログラミングGroovy」3、5、8章執筆JGGUG運営委員ブログ“Grな日々”“Grails徹底入門”2章執筆GroovyServ開発者

22011年5月28日土曜日

Page 3: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

本パートの内容

3

例1: ワードカウント処理例2: 変更不能クラスを定義するGroovyの設計理念(私見)まとめ宮本武蔵になろう!

2011年5月28日土曜日

Page 4: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

例1:ワードカウント処理

4

引数で与えたテキストファイル中の単語の頻度を数える

$ cat input.txt That that is is that that isnot is not is that it it is

$ java WordCount input.txt 1: [That]2: [not]2: [it]4: [that]6: [is]

2011年5月28日土曜日

Page 5: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Java版WordCount:48行

import java.util.Comparator;import java.util.HashMap;import java.util.Map;import java.util.Set;import java.util.List;import java.util.Arrays;import java.io.FileReader;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.IOException;

public class WordCount {  @SuppressWarnings(value = "unchecked")  public static void main(String[] args) {    FileReader fis = null;    BufferedReader br = null;    try {      HashMap<String, Integer> map = new HashMap<String, Integer>();      fis = new FileReader(args[0]);      br = new BufferedReader(fis);      String line;      while ((line = br.readLine()) != null) {        for (String it: line.split("\\s+")) {          map.put(it, (map.get(it)==null) ? 1 : (map.get(it) + 1));        }      }

     Set<Map.Entry<String, Integer>> entrySet = map.entrySet();     Object[] list = entrySet.toArray();    Comparator comp = new Comparator(){       public int compare(Object o1, Object o2) {         Map.Entry<String, Integer> e1 = (Map.Entry<String, Integer>) o1;         Map.Entry<String, Integer> e2 = (Map.Entry<String, Integer>) o2;        return e1.getValue() - e2.getValue();        }      };      Arrays.sort(list, comp);      for (Object it: list) {        Map.Entry<String, Integer> entry = (Map.Entry<String, Integer>)it;        System.out.println(entry.getValue() + ": ["+entry.getKey()+"]");      }    }    catch (IOException e) {      try {if (br != null) br.close();}catch(IOException ioe){}      try {if (fis != null)fis.close();}catch(IOException ioe){}      e.printStackTrace();    }  }}

52011年5月28日土曜日

Page 6: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版WordCount(9行)

def map = [:].withDefault{0} new File(args[0]).eachLine {   it.split(/\s+/).each {     map[it]++    } } map.entrySet().sort{it.value}.each {   println "${it.value}: [${it.key}]" }

6

これだけですよ!これだけ

2011年5月28日土曜日

Page 7: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Java版からボイラープレートコードを除去

import java.util.Comparator;import java.util.HashMap;import java.util.Map;import java.util.Set;import java.util.List;import java.util.Arrays;import java.io.FileReader;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.IOException;

public class WordCount {    @SuppressWarnings(value = "unchecked")    public static void main(String[] args) {        FileReader fis = null;        BufferedReader br = null;        try {            HashMap<String, Integer> map = new HashMap<String, Integer>();            fis = new FileReader(args[0]);            br = new BufferedReader(fis);            String line;            while ((line = br.readLine()) != null) {                for (String it: line.split("\\s+")) {                    map.put(it, (map.get(it)==null) ? 1 : (map.get(it) + 1));                }            }

            Set<Map.Entry<String, Integer>> entrySet = map.entrySet();            Object[] list = entrySet.toArray();            Comparator comp = new Comparator(){                public int compare(Object o1, Object o2) {                    Map.Entry<String, Integer> e1 = (Map.Entry<String, Integer>) o1;                    Map.Entry<String, Integer> e2 = (Map.Entry<String, Integer>) o2;                    return e1.getValue() - e2.getValue();                }            };            Arrays.sort(list, comp);            for (Object it: list) {                Map.Entry<String, Integer> entry = (Map.Entry<String, Integer>)it;                System.out.println(entry.getValue() + ": ["+entry.getKey()+"]");            }        }        catch (IOException e) {            try {if (br != null) br.close();}catch(IOException ioe){}            try {if (fis != null)fis.close();}catch(IOException ioe){}            e.printStackTrace();        }    }}

7「プログラムの動

作記述」を抽出するとこれだけ

2011年5月28日土曜日

Page 8: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版WordCount(9行)

def map = [:].withDefault{0} // valueのデフォルト値が0のマップmapnew File(args[0]).eachLine { // 引数に与えたファイルの各行に対し、  it.split(/\s+/).each {     // 正規表現/\s+/で区切り、それぞれに対し    map[it]++                // それをmapのキーとする値に1を足す  }}map.entrySet().sort{it.value}.each {// mapのentrySetをvalueでソート  println "${it.value}: [${it.key}]"// それぞれのkey,valueを表示}

82011年5月28日土曜日

Page 9: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版WordCount(9行)

def map = [:].withDefault{0} // valueのデフォルト値が0のマップmapnew File(args[0]).eachLine { // 引数に与えたファイルの各行に対し、  it.split(/\s+/).each {     // 正規表現/\s+/で区切り、それぞれに対し    map[it]++                // それをmapのキーとする値に1を足す  }}map.entrySet().sort{it.value}.each {// mapのentrySetをvalueでソート  println "${it.value}: [${it.key}]"// それぞれのkey,valueを表示}

9

セミコロン、主なパッケージのimport、チェック例外のtry-catchなど省略可能。

2011年5月28日土曜日

Page 10: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版WordCount(9行)

def map = [:].withDefault{0} // valueのデフォルト値が0のマップmapnew File(args[0]).eachLine { // 引数に与えたファイルの各行に対し、  it.split(/\s+/).each {     // 正規表現/\s+/で区切り、それぞれに対し    map[it]++                // それをmapのキーとする値に1を足す  }}map.entrySet().sort{it.value}.each {// mapのentrySetをvalueでソート  println "${it.value}: [${it.key}]"// それぞれのkey,valueを表示}

10

[:]はマップのリテラル。[a:1, b:2]の様に書ける。ちなみにリストのリテラルは[1,2,3]の様に書ける。

2011年5月28日土曜日

Page 11: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版WordCount(9行)

def map = [:].withDefault{0} // valueのデフォルト値が0のマップmapnew File(args[0]).eachLine { // 引数に与えたファイルの各行に対し、  it.split(/\s+/).each {     // 正規表現/\s+/で区切り、それぞれに対し    map[it]++                // それをmapのキーとする値に1を足す  }}map.entrySet().sort{it.value}.each {// mapのentrySetをvalueでソート  println "${it.value}: [${it.key}]"// それぞれのkey,valueを表示}

11

eachLineはクロージャを引数にとるjava.io.Fileクラスの追加メソッド。1行ごと読み取り、最後に自動クローズ処理。

2011年5月28日土曜日

Page 12: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版WordCount(9行)

def map = [:].withDefault{0} // valueのデフォルト値が0のマップmapnew File(args[0]).eachLine { // 引数に与えたファイルの各行に対し、  it.split(/\s+/).each {     // 正規表現/\s+/で区切り、それぞれに対し    map[it]++                // それをmapのキーとする値に1を足す  }}map.entrySet().sort{it.value}.each {// mapのentrySetをvalueでソート  println "${it.value}: [${it.key}]"// それぞれのkey,valueを表示}

12

mapのキーが存在しないときの初期値は通常Javaと同じくnullだが、withDefaultで0に変更することで++が使える

2011年5月28日土曜日

Page 13: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版WordCount(9行)

def map = [:].withDefault{0} // valueのデフォルト値が0のマップmapnew File(args[0]).eachLine { // 引数に与えたファイルの各行に対し、  it.split(/\s+/).each {     // 正規表現/\s+/で区切り、それぞれに対し    map[it]++                // それをmapのキーとする値に1を足す  }}map.entrySet().sort{it.value}.each {// mapのentrySetをvalueでソート  println "${it.value}: [${it.key}]"// それぞれのkey,valueを表示}

13

sortに比較ロジックをクロージャで渡し、ソート。逆順なら sort {-it.value }で。

2011年5月28日土曜日

Page 14: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版WordCount(9行)

def map = [:].withDefault{0} // valueのデフォルト値が0のマップmapnew File(args[0]).eachLine { // 引数に与えたファイルの各行に対し、  it.split(/\s+/).each {     // 正規表現/\s+/で区切り、それぞれに対し    map[it]++                // それをmapのキーとする値に1を足す  }}map.entrySet().sort{it.value}.each {// mapのentrySetをvalueでソート  println "${it.value}: [${it.key}]"// それぞれのkey,valueを表示}

14

文字列定数中の $変数名、${式} はその値に展開される。(GString)

2011年5月28日土曜日

Page 15: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

例2:変更不能クラスを定義する

15

フィールドの値を変更できない(Immutable)クラスを定義する

参考: Effective Java (2nd Edition), p73: Item15 Minimize mutability

クラスはfinal宣言全フィールドをfinalかつprivateにgetterメソッドの定義Mutableなデータ型(配列やStringBufferやDateなど)のフィールドに対しては「防御的コピー」を行うすべてのフィールドを初期化するコンストラクタを定義するフィールドの値に基づくequals, hashCode, toStringを定義する

2011年5月28日土曜日

Page 16: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

public final class Person { private final String firstName; private final String lastName;

public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; }

public String getFirstName() { return firstName; }

public String getLastName() { return lastName; }

@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; }

@Override public boolean equals(Object obj) { if (this == obj) return true;

if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (firstName == null) { if (other.firstName != null) return false; } else if (!firstName.equals(other.firstName)) return false; if (lastName == null) { if (other.lastName != null) return false; } else if (!lastName.equals(other.lastName)) return false; return true; }

@Override public String toString() { return "Person(firstName:" + firstName + ", lastName:" + lastName + ")"; }

}

2011 05/28 仙台Slide #

Java

Java版 変更不能クラス: 57行

16

参考: http://groovy.codehaus.org/Immutable+AST+Macro

2011年5月28日土曜日

Page 17: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

public final class Person { private final String firstName; private final String lastName;

public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; }

public String getFirstName() { return firstName; }

public String getLastName() { return lastName; }

@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; }

@Override public boolean equals(Object obj) { if (this == obj) return true;

if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (firstName == null) { if (other.firstName != null) return false; } else if (!firstName.equals(other.firstName)) return false; if (lastName == null) { if (other.lastName != null) return false; } else if (!lastName.equals(other.lastName)) return false; return true; }

@Override public String toString() { return "Person(firstName:" + firstName + ", lastName:" + lastName + ")"; }

}

2011 05/28 仙台Slide #

Java

Java版 変更不能クラス: 57行

16

作成が大変、ミスが混入しやすく、

意図がコード上明確ではない

参考: http://groovy.codehaus.org/Immutable+AST+Macro

2011年5月28日土曜日

Page 18: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版変更不能クラス: 4行

@Immutableclass Person { String firstName, lastName}

17

これだけですよ!これだけ

2011年5月28日土曜日

Page 19: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版変更不能クラス: 4行

@Immutableclass Person { String firstName, lastName}

17

これだけですよ!これだけ

x = new Person("Junji","Uehara")assert x.lastName == "Uehara"x.firstName = "abc" //==> groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: firstName for class: Person

2011年5月28日土曜日

Page 20: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

x = new Person("Junji","Uehara")assert x.lastName == "Uehara"x.firstName = "abc"

2011 05/28 仙台Slide #

Java

Groovy版変更不能クラス: 4行

@Immutableclass Person { String firstName, lastName}

18

Groovyではフィールドを定義するだけでgetter,setterが自動生成される。(この場合はgetterのみ)

2011年5月28日土曜日

Page 21: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版変更不能クラス: 4行

@Immutableclass Person { String firstName, lastName}

19

フィールドの参照はgetterメソッドの呼び出しとみなされる。

x = new Person("Junji","Uehara")assert x.lastName == "Uehara"x.firstName = "abc"

2011年5月28日土曜日

Page 22: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovy版変更不能クラス: 4行

@Immutableclass Person { String firstName, lastName}

20

フィールドへの代入はsetterメソッドへの呼び出しとみなされる。

x = new Person("Junji","Uehara")assert x.lastName == "Uehara"x.firstName = "abc"

2011年5月28日土曜日

Page 23: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovyの設計理念(私見)Javaへの愛(類似)

Javaへの憎しみ(差異)

212011年5月28日土曜日

Page 24: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovyの設計理念(私見)Javaへの愛(類似)

Javaへの憎しみ(差異)

21

文法親和性、JVM共通、Groovyクラス=Javaクラス、ツール・ライブラリ共通・・・

2011年5月28日土曜日

Page 25: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovyの設計理念(私見)Javaへの愛(類似)

Javaへの憎しみ(差異)

21

文法親和性、JVM共通、Groovyクラス=Javaクラス、ツール・ライブラリ共通・・・

何を違いとするか? 差別化するか?

2011年5月28日土曜日

Page 26: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovyの設計理念(私見)Javaへの愛(類似)

Javaへの憎しみ(差異)

21

文法親和性、JVM共通、Groovyクラス=Javaクラス、ツール・ライブラリ共通・・・

何を違いとするか? 差別化するか?

その人を知りたければ

その人が

何に対して怒りを感じる

かを知るべし…ゴン 言語を知り

たければその言語が

何に対して怒りを感じる

かを知るべし

2011年5月28日土曜日

Page 27: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

Groovyの設計理念(私見)Javaへの愛(類似)

Javaへの憎しみ(差異)

21

ボイラープレートコードをとことん排除する!! 憎しみすら感じる程に・・。

文法親和性、JVM共通、Groovyクラス=Javaクラス、ツール・ライブラリ共通・・・

何を違いとするか? 差別化するか?

その人を知りたければ

その人が

何に対して怒りを感じる

かを知るべし…ゴン 言語を知り

たければその言語が

何に対して怒りを感じる

かを知るべし

2011年5月28日土曜日

Page 28: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

まとめJava+Groovyが一体となってJava技術の適用領域を広げる

22

JavaC Ruby

HaskelPHP

C++Python

Java + Groovy

システム記述 アプリケーション記述

ミドルウェアOS記述DSLデバイスドライバ記述

ハイパフォーマンス

2011年5月28日土曜日

Page 29: Let's go Developer 2011 sendai Let's go Java Developer (Programming Language Groovy Part)

2011 05/28 仙台Slide #

Java

宮本武蔵になろう!

23

Java Groovy

2011年5月28日土曜日