Существует ли безопасная для типов реализация Java 'Reduce'?
-
03-07-2019 - |
Вопрос
Мне часто нужно запускать Reduce (также называемый foldl / foldr, в зависимости от вашего контекста) в Java, чтобы объединять элементы Itterable. Р>
Reduce принимает коллекцию / iterable / etc, функцию двух параметров и необязательное начальное значение (в зависимости от деталей реализации). Эта функция последовательно применяется к элементу коллекции и выводу предыдущего вызова метода Reduce до тех пор, пока все элементы не будут обработаны, и возвращает окончательное значение.
Есть ли безопасная от типов реализация Reduce в любом распространенном Java-API? Коллекции 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;
}
}
Я уверен, что существует множество синтаксических ошибок, но это главное (есть несколько вариантов того, как получить значение пустого аккумулятора. Затем, чтобы использовать его на конкретном итераторе, просто определите свой Reducer на летать:
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());
в зависимости от того, как работает ваш итератор, он может сгибаться влево или вправо, если итератор движется в правильном направлении.
надеюсь, это поможет.
Другие советы
Исходя из предположения Люка, здесь приведена законная реализация 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;
}
Попробуйте пакет функторов общих ресурсов . Он всегда был в песочнице, но я думаю, что он будет делать то, что вы хотите.