目下勉強中のScala という言語を使って、
題材は前回のものと同じです。
を利用しています。
で利用できます。
また https://github.com/ueshin/hadoop-scala-aggregate/tree/hadoop-scala-aggregate-0.20.1 でブラウズできます。
MapReduce
を実装してみました。題材は前回のものと同じです。
- Hadoop: 0.20.2
- Scala: 2.8.0.Beta1
を利用しています。
$ git clone https://github.com/ueshin/hadoop-scala-aggregate.git
$ cd hadoop-scala-aggregate
$ git checkout hadoop-scala-aggregate-0.20.1
で利用できます。
また https://github.com/ueshin/hadoop-scala-aggregate/tree/hadoop-scala-aggregate-0.20.1 でブラウズできます。
ポイント
pom.xml
pom.xmlファイルはこちらを参照。当たり前ですが、Hadoopへの依存とScalaへの依存を両方共記述します。
mvnでScalaプロジェクトを作った後にHadoopの分を追加していった方が楽でした。
Scalaで書くと
当該箇所のソースファイルはこちらを参照。今回は結構単純に移植しただけなので、Scalaっぽさはあまり出ていません。
とはいえ、Scalaって便利だなぁと改めて思った点を上げます。
Java版とScala版を並べて見比べてもらうと、言いたいことがわかりやすいかもしれません。
L52: case PATTERN(ip, accessDate, url)
正規表現の場合、グループを変数に格納するのが上記のようなコードで記述することが出来ます。
これを覚えると、Javaの冗長な正規表現マッチングが嫌になります。
ここでは正規表現のパターンマッチですが、caseクラスを使った場合にも同様のことができます。
L75/L88: values.foldLeft(0) { _ + _.get }
Javaだとforループでちまちまと足し算をしていくところですが、Scalaではこのような記述ができます。
この他にも、関数型言語の宣言的で簡潔な表現をたくさん備えているので、コードがシンプルになっていきます。
逆に
これはたぶん僕の勉強不足なんですが、49: context: Mapper[LongWritable, Text, AccessWritable, IntWritable]#Context
73: context: Reducer[AccessWritable, IntWritable, AccessWritable, IntWritable]#Context
84: context: Reducer[AccessWritable, IntWritable, Text, IntWritable]#Context
この引数の型はこうしか書けないのだろうか。
ものすごく冗長な事になっちゃってます。
簡潔に書ける方法をご存じの方は是非とも教えてください。