私は最近 Scala で働き始めましたが、それが関数型パラダイムとの最初の接触でした。私は Java の大ファンですが、認めますが、Java には機能的なパラダイムが欠けていることがあります。
そういうわけで、私は最近、ミニペットプロジェクトを開始して、そのようなことが Java である程度達成できるかどうかを確認しました。
配列リストの簡単な変更から始めました。これがこれまでの結果です。
要素に関数を適用するためにコレクションが実装する必要があるインターフェイス:
public interface Functionalizable<E> {
public Collection<E> apply(Function<E> f);
}
単一の要素に関数を適用するためのメソッドを定義するインターフェイス:
public interface Function<E> {
public E apply(E e);
}
要素に関数を適用できる配列リストに基づく具象クラス:
public class FunctionArrayList<E> implements List<E>, Functionalizable<E> {
private List<E> list;
//implemented methods from `List` interface and ctors
@Override
public List<E> apply(Function<E> f) {
List<E> applied = new FunctionArrayList<>(this.list.size());
for (E e : this.list) {
applied.add(f.apply(e));
}
return applied;
}
}
Integer の小さなテスト メソッドを作成しましたが、問題なく動作します。
コード:
List<Integer> listOfIntegersBefore = new FunctionArrayList<>();
listOfIntegersBefore.add(-1);
listOfIntegersBefore.add(0);
listOfIntegersBefore.add(1);
listOfIntegersBefore.add(2);
listOfIntegersBefore.add(3);
listOfIntegersBefore.add(4);
System.out.println("Before<Integer>: " + listOfIntegersBefore.toString());
List<Integer> listOfIntegersAfter = ((FunctionArrayList<Integer>) listOfIntegersBefore).apply(new Function<Integer>() {
@Override
public Integer apply(Integer e) {
return (e + 1);
}
});
System.out.println("After<Integer> : " + listOfIntegersAfter.toString());
出力:
Before<Integer>: [-1, 0, 1, 2, 3, 4]
After<Integer> : [0, 1, 2, 3, 4, 5]
しかし、List でもう少し複雑なことをしようとすると、好きではない多くの型キャストになってしまいます (できるだけ避けたいと思います)。
コード:
List<List<Integer>> listOfListOfIntegersBefore = new FunctionArrayList<>();
List<Integer> temp = new FunctionArrayList<>();
temp.add(1);
listOfListOfIntegersBefore.add(temp);
temp = new FunctionArrayList<>();
temp.add(1);
temp.add(2);
listOfListOfIntegersBefore.add(temp);
temp = new FunctionArrayList<>();
temp.add(1);
temp.add(2);
temp.add(3);
listOfListOfIntegersBefore.add(temp);
temp = new FunctionArrayList<>();
temp.add(1);
temp.add(2);
temp.add(3);
temp.add(4);
listOfListOfIntegersBefore.add(temp);
List<List<Integer>> listOfListOfIntegersAfter = (List<List<Integer>>) ((Functionalizable<List<Integer>>) listOfListOfIntegersBefore).apply(new Function<List<Integer>>() {
@Override
public List<Integer> apply(List<Integer> e) {
List<Integer> list = new FunctionArrayList<>(e);
return ((FunctionArrayList<Integer>) list).apply(new Function<Integer>() {
@Override
public Integer apply(Integer e) {
return (e + 1);
}
});
}
});
System.out.println("Before<List<Integer>>: " + listOfListOfIntegersBefore);
System.out.println("After<List<Integer>> : " + listOfListOfIntegersAfter);
出力:
Before<List<Integer>>: [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]
After<List<Integer>> : [[2], [2, 3], [2, 3, 4], [2, 3, 4, 5]]
すでに述べたように、キャストは避けたいと思います。Type safety: Unchecked cast from List<List<Integer>> to Functionalizable<List<Integer>>
さらに、Eclipseは次の行について警告します。
List<List<Integer>> listOfListOfIntegersAfter = (List<List<Integer>>) ((Functionalizable<List<Integer>>) listOfListOfIntegersBefore).apply(new Function<List<Integer>>() {
...
}
それを達成するエレガントな方法はありますか?