ここで、 LambdaJライブラリが役立ちます。 その目的は、コレクションの操作プロセスを簡素化して、データの静的な型指定を無視することなく、いくつかの関数型プログラミング手法を実装することでコードのエラーを減らし、可読性を高めることです。 静的型付けは言語の利点であり、コードの信頼性を大幅に高めるため、後者の事実は非常に重要です。
LambdaJを使用した例を考えてみましょう。 50'000以上購入した最年少の買い手の年齢を見つけます。
古典的な(反復的な)方法:
int age = Integer.MAX_VALUE;
for (Sale sale : sales) {
if (sale.getCost() > 50000.00) {
int buyerAge = sale.getBuyer().getAge();
if (buyerAge < age)
age = buyerAge;
}
}
LambdaJメソッド:
int age = min(forEach( select (sales, having(
on(Sale. class ).getCost(), greaterThan(50000.00)).getBuyer()))),
on(Person. class ).getAge());
機能性
上記の例から、ライブラリがコレクションを操作するための一種のDSLをプログラマに提供していることがわかります。 この場合のドメインはJavaコレクションであり、言語構成体はLambdaJライブラリの対応するクラスの静的にインポートされたメソッドです。
それでは、LambdaJは何をしますか? 機能のリストはほぼ次のとおりです。
- 指定された条件に従って要素をフィルタリングします。
- 所定の規則に従った各要素の変更。
- 各要素から指定されたプロパティを取得します。
- プロパティの1つに基づいて要素をソートします。
- プロパティの1つに基づいて要素にインデックスを付けます。
- 1つ以上のプロパティに基づいて要素をグループ化します。
- 各要素に対して指定されたメソッドを呼び出す。
- 要素またはそれらのプロパティのいずれかの集約(たとえば、合計)。
- 1つのオブジェクトセットのプロパティを別のオブジェクトセットのプロパティに投影(コピー)(ドメイン-> DTO);
- 要素またはそれらのプロパティの文字列表現の連結。
例
フィルタリング
List <Integer> biggerThan3 = filter(greaterThan(3), asList(1, 2, 3, 4, 5));
List <Person> oldFriends = filter(having(on(Person. class ).getAge(), greaterThan(30)), meAndMyFriends);
集計
int totalAge = sum(meAndMyFriends, on(Person. class ).getAge());
プロパティを取得する
List <Integer> lengths = convert(strings, new PropertyExtractor( "length" ));
List <Integer> ages = extract(persons, on(Person. class ).getAge());
索引付け
Map< String , Person> personsByName = index(persons, on(Person. class ).getFirstName());
仕分け
List <Person> sorted = sort(persons, on(Person. class ).getAge());
グルーピング
Group<Person> group = group(meAndMyFriends, by(on(Person. class ).getAge()));
Group<Person> group29aged = group.findGroup( "29" );
性能
ご存知のように、利便性の代価はパフォーマンスです。 LambdaJの場合、オーバーヘッドは平均2.5倍です[ * ]。 これは確かに悲しいことです。 ただし、コレクションの操作がアプリケーションのプロセッサ時間のわずかな部分を占める場合、作業の利便性の利点がマイナスのオーバーヘッドを大幅に上回る可能性があります。
PS
この記事は、 公式のWiki LambdaJの任意の部分の無料翻訳です。 詳細については、こちらをご覧ください。