Java Day TokyoとかJJUG CCCで話題になっていたGS-Collectionsのcode kataをドキュメントを読みながらすこしだけ(エクササイズ2まで)やってみたので、その感想。
なお、使い方的なのは下記参照。
エクササイズ2までやってみた感じ、GS-Collectionsの効率が云々というのはよくわからなかったのですが、collect
とかselect
などに対するFunction
やPredicate
の作り方というのが非常に参考になります。
kataの例をそのまま引っ張ってきて恐縮ですが、オブジェクトCustomer
のコレクションMutableList<Customer>
から名前の一覧MutableList<String>
を取得するとき、だいたいこのように書いてしまいます。
MutableList<Customer> customers = ...
MutableList<String> names = customers.collect(Customer::getName);
もちろん、これで問題はないのですが、Customer
にこのようなボイラープレートなコードを作ってしまおうと提案してきます。
public final class Customer { public static Function<Customer, String> TO_NAME = Customer::getName; private final String name; public String getName() { return name; } }
これを準備すると、先のコードはこうなります。
MutableList<Customer> customers = ...
MutableList<String> names = customers.collect(Customer.TO_NAME);
Predicate
については、GS-Collectionsに便利なユーティリティクラスがあります。
まずは、ユーティリティクラスを使わない場合のコードから。
先ほどのMutableList<Customer>
からロンドンに住んでいるCustomer
だけを取り出します。そのコードはこのようになります。
MutableList<Customer> customers = ... MutableList<Customer> customersInLondon = customers.select( c -> c.getAddress().equals("ロンドン"));
フィールドの値を比較しているだけですが、ユーティリティクラスPredicates
を使うと、よりエレガントになります。
MutableList<Customer> customers = ... MutableList<Customer> customersInLondon = customers.select( Predicates.attributeEqual(Customer::getAddress, "ロンドン"));
タイプする量は増えているのは内緒です。
これをstaticインポートにして、かつ先ほどのFunction
のボイラープレートコードを排除するパターンを使うと、こうなります。
public final class Customer { public static Function<Customer, String> TO_ADDRESS = Customer::getAddress; // 以下略 }
MutableList<Customer> customers = ... MutableList<Customer> customersInLondon = customers.select( attributeEqual(Customer.TO_ADDRESS, "ロンドン"));
なんか、読みやすくなった気がしなくもない。TO_ADDRESS
はADDRESS
でもいい気がしなくもない。
以上、まだエクササイズ2までやってみた感想ですが、GS-Collectionsの設計思想のようなものが見られるので(大袈裟)、GS-Collectionsをうまく使ってみたい方はcode kataから取り組むとよいかもしれません。
なお、エクササイズ一つはドキュメントを読みながらでも15分くらいでできます。
【追記 2015/04/16 11:19】
GS Collections Kata をひと通りやった - blog.64p.org
早い(・・;)