2008-10-21 3 views
7

Мне часто нужно запустить сокращение (также называемое foldl/foldr, в зависимости от ваших контекстов) в java для объединения элементов Itterable.Есть ли безопасная Java-реализация «уменьшить»?

Уменьшение принимает сбор/итерацию/etc, функцию из двух параметров и необязательное начальное значение (в зависимости от деталей реализации). Функция последовательно применяется к элементу коллекции и выводу предыдущего вызова сокращения до тех пор, пока все элементы не будут обработаны и не вернет окончательное значение.

Есть ли безопасная реализация сокращения в любом распространенном java-api? Google Collectionsкажется, как будто он должен иметь один, но я не смог его найти. (возможно, потому, что я не знаю, какие другие названия он будет использовать.)

ответ

2

вы, вероятно, может свернуть свой собственный общий довольно легко, основываясь на описании:

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; 
    } 
} 

Я уверен, что есть тонны ошибок синтаксиса но это основной момент (есть несколько вариантов, которые вы могли бы сделать о том, как получить пустое значение аккумулятора. Затем, чтобы использовать его на конкретном итераторе, просто определите свой редуктор «на лету»:

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()); 

В зависимости от того, как работает ваш итератор, это может складываться влево или складываться вправо, пока итератор идет в правильном направлении.

надеюсь, что это поможет.

1

Попробуйте commons functor package. Это было в песочнице навсегда, но я думаю, что он будет делать то, что вы хотите.

+0

Это выглядит интересно, но это не выглядит, как он будет вписываться в библиотеке существующих Java коллекций, которые хорошо. Если ничего больше не появится, я углубится в это глубже. – rcreswick 2008-10-21 19:05:13

+1

Да, это сложно. Я думаю, вы можете приготовить жареный картофель. Похоже, что ключом к интеграции с коллекциями является класс IteratorToGeneratorAdapter. – sblundy 2008-10-21 19:09:18

2

Основываясь на предложении Люка, вот законная реализация 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; 
} 
Смежные вопросы