Frage

Ich muss oft laufen reduzieren (auch foldl / foldr genannt, auf Ihrem Kontext abhängig) in Java-Elemente eines Itterable zu aggregieren.

Reduzieren Sie nimmt eine Sammlung / iterable / etc, eine Funktion von zwei Parametern und ein optionaler Startwert (abhängig von den Implementierungsdetails). Die Funktion wird mit einem Element der Sammlung aufeinanderfolgend angelegt, und die Ausgabe des vorherigen Aufruf zu reduzieren, bis alle Elemente verarbeitet worden sind, und gibt den Endwert.

Gibt es eine typsichere Implementierung in alle gängigen Java-API reduzieren? Google Sammlungen scheint wie es ein sollte, aber ich habe nicht in der Lage gewesen, es zu finden. (Möglicherweise, weil ich nicht weiß, welche anderen Namen würde es verwenden.)

War es hilfreich?

Lösung

Sie könnten wahrscheinlich rollen Sie Ihre eigene generische ziemlich leicht, auf der Grundlage Ihrer Beschreibung:

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

Dann mit dem Strategie-Muster:

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

Ich bin sicher, dass eine Tonne Syntaxfehler gibt es aber das ist der wichtigste Punkt (es gibt ein paar Möglichkeiten Sie machen könnten, wie den leeren Akku Wert zu erhalten. Dann ist es auf einem bestimmten Iterator zu verwenden nur Ihre Reducer auf dem definiert fliegen:

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

Je nachdem, wie Ihr Iterator funktioniert das linke Falte oder falten rechts solange der Iterator in die richtige Richtung geht.

hoffe, das hilft.

Andere Tipps

Basierend auf Lukes Vorschlag, hier ist eine legitime Java-Implementierung:

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

Versuchen Sie, die commons Funktors Paket rel="nofollow. Es ist für immer in Sandbox, aber ich denke, es wird tun, was Sie wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top