概要
酔っ払いが Java の "filter" について勢いで書いた雑な記事です。
filter とは
RxJava や Stream API でおなじみの彼です。Stream の要素数を変化させます。
問題
次のコードの出力結果はどうなるでしょうか?なお、main メソッド内で実行されるものとします。
IntStream.range(1, 10).filter(i -> {return i % 2 == 0;}).forEach(i -> System.out.println(i));
答え
2
4
6
8
そうですね、2で割り切れる数が Stream に残って出力されます。
filter が意味するもの
あまり英語に強くない私は filter と聞いたらコーヒーフィルタを思い浮かべます。コーヒーフィルタでほしい物はコーヒーであって、フィルタの中に残る豆ではないはずです。が、Javaのライブラリではそのメタファでは通じません。filter はその Stream に「残すもの」を指定するメソッドです。前述の RxJava や Stream API だけでなく、Storm でも同様(残すものをtrueにする)なので、英語ではそれが一般的なのでしょう。以前、英語の得意な同僚に聞いた限りでは、取り除くのは filter out と言うそうで、単に filter だけであれば「残す」というニュアンスがあるらしいです。
ただ、英単語はいくらでもあるのに、意味に曖昧なところのある語をわざわざ採用したのはなかなか肯定のしがたい気持ちがあります。辞書を引く時間をコーディングやリファクタリングに使いたいですね。はい、「英語を勉強すればいいだけだ」というのはもっともです。
最高にイカした Collection Framework の Eclipse Collections では
filter に相当するメソッドは select という名前です。select であれば何をやるのか明確ですね。少なくとも「このメソッドは要素を残すのか?取り除くのか?」と初学者が迷うことはないはずです。 一方、 filter と逆の操作をするメソッドもあって、それは reject という名前です。いいですね。みなぎるセンスを感じます。
私が昨年の JavaOne 報告会で Eclipse Collections を知った時、 Java8 の Stream API にこれらのメソッド名が採用されなかったのを残念に思いました。セッションで聞いた話によると、Eclipse Collections を将来的に JDK に入れることを目標としていらっしゃるそうなので、早いうちにそうなることを望んでいる開発者がここに1人いるということを述べてこの記事を終わることにします。
酔いがさめたら記事を消しているかもしれないです。