'reduce'のタイプセーフなJava実装はありますか?
-
03-07-2019 - |
質問
Iterableの要素を集約するには、javaでreduce(foldl / foldrとも呼ばれます)をjavaで実行する必要があります。
Reduceは、collection / iterable / etc、2つのパラメーターの関数、およびオプションの開始値(実装の詳細に応じて)を取ります。この関数は、すべての要素が処理されるまでコレクションの要素と前回のreduceの呼び出しの出力に連続して適用され、最終値を返します。
一般的なJava APIには、reduceのタイプセーフな実装はありますか? Googleコレクション があるはずですが、できませんでしたそれを見つけるために。 (おそらく、他の名前がどのような名前を使用するのかわからないためです。)
解決
説明に基づいて、おそらく独自のジェネリックを簡単に展開できます:
public interface Reducer<A, T>
{
public A foldIn(A accum, T next);
}
次に、戦略パターンを使用します:
public class Reductor<A, T>
{
private Reducer<A, T> worker;
public Reductor<A, T>(Reducer<A, T> worker)
{
this.worker = worker;
}
public A fold(A rval, Iterator<T> itr)
{
while(itr.hasNext())
{
A rval = worker.foldIn(rval, itr.next());
}
return rval;
}
}
構文エラーはたくさんあると思いますが、それが主なポイントです(空のアキュムレータ値を取得する方法についてはいくつかの選択肢があります。特定のイテレータで使用するには、Reduceをフライ:
Reductor r = new Reductor<A, T>(new Reducer<A, T>()
{
public A foldIn(A prev, T next)
{
A rval;
//do stuff...
return rval;
}
}
A fold = r.fold(new A(), collection.getIterator());
イテレータの動作に応じて、イテレータが正しい方向に進む限り、これは左に折り畳まれたり、右に折り畳まれたりします。
これが役に立てば幸いです。
他のヒント
Lukeの提案に基づき、正当なJava実装を以下に示します。
public interface Reducer<A,T>
{
A foldIn(A accum, T next);
}
public static <T> T reduce(final Reducer<T,T> reducer,
final Iterable<? extends T> i)
{
T result = null;
final Iterator<? extends T> iter = i.iterator();
if (iter.hasNext())
{
result = iter.next();
while (iter.hasNext())
{
result = reducer.foldIn(result, iter.next());
}
}
return result;
}
public static <A,T> A reduce(final Reducer<A,T> reducer,
final Iterable<? extends T> i,
final A initializer)
{
A result = initializer;
final Iterator<? extends T> iter = i.iterator();
while (iter.hasNext())
{
result = reducer.foldIn(result, iter.next());
}
return result;
}
commons functorパッケージを試してください。それは永遠にサンドボックスにありましたが、あなたが望むことをするだろうと思います。
所属していません StackOverflow