Pergunta

Muitas vezes eu preciso executar reduzir (também chamado foldl / foldr, dependendo de seus contextos) em Java para elementos agregados de um Itterable.

Reduzir leva uma coleção / iterable / etc, uma função de dois parâmetros, e um valor inicial opcional (dependendo dos detalhes de implementação). A função é sucessivamente aplicado a um elemento de recolha e a saída da chamada anterior de reduzir até que todos os elementos tiverem sido processados, e retorna o valor final.

Existe uma implementação tipo seguro de reduzir em qualquer api java comum? Google Collections parece como ele deve ter um, mas eu não tenho sido capaz Para encontrar isso. (Possivelmente porque eu não sei o que outros nomes que iria usar.)

Foi útil?

Solução

Você provavelmente poderia rolar o seu próprio genérico muito facilmente, com base em sua descrição:

public interface Reducer<A, T>
{
    public A foldIn(A accum, T next);
}

Em seguida, usando o padrão de estratégia:

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

Estou certo de que há uma tonelada de erros de sintaxe, mas esse é o ponto principal (há algumas opções que você pode fazer sobre como obter o valor do acumulador vazio. Depois de usá-lo em um iterador especial apenas definir o seu redutor na voar:

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

dependendo de como o iterador funciona este pode dobrar para a esquerda ou dobre a direita enquanto o iterador vai na direção certa.

espero que isso ajude.

Outras dicas

Com base na sugestão de Lucas, aqui é uma implementação Java legítimo:

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

Tente o commons pacote functor . Tem sido na caixa de areia para sempre, mas eu acho que ele vai fazer o que quiser.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top