はじめに
実装を実際にされている際、あるリストにあるモデルのフィールドから一つずつ要素を取り出し、一つのリストを作成したい場面は頻繁にあると思います。
今回は、関数型インターフェースのBiConsumerを応用し、そんなアルゴリズムを汎用メソッドにしてサービスメソッドの可読性を上げるリファクタリングテクニックを紹介します。
サンプルコード
util.java
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.Function;
class B {
String fieldB;
public B(String fieldB) { this.fieldB = fieldB; }
public String getFieldB() { return fieldB; }
}
public class Main {
public static void main(String[] args) {
List<ModelB> listA = List.of(new B("apple"), new B("banana"), new B("cherry"));
List<String> listC = new ArrayList<>();
// 汎用的な処理
extrModelFieldsAndAddToList(listA, ModelB::getFieldB, listC, Collection::add);
// 結果確認
listC.forEach(System.out::println);
}
public static <T, R> void extrModelFieldsAndAddToList(
Iterable<T> source,
Function<T, R> extractor,
Collection<R> target,
BiConsumer<Collection<R>, R> adder) {
for (T item : source) {
R value = extractor.apply(item);
adder.accept(target, value);
}
}
}
BiConsumer, R> を使うことで、「どのコレクションに何をどう追加するか」を外部から指定できます。
Collection::add をメソッド参照として渡せるので、非常に簡潔。
必要があれば、Set, Queue, カスタムコレクション, ログ出力用のList などにも柔軟に適用できます。