2010-10-28 21 views
8

offensichtlich Nach funktioniert, aber ich weiß nicht Einzelteile mögen in Tuple wickeln,Guava Funktionsargumente

ImmutableMap<String, Function<Tuple2<Double>, Double>> op = new // 
    ImmutableMap.Builder<String, Function<Tuple2<Double>, Double>>() 
      .put("+", new Function<Tuple2<Double>, Double>() { 
       @Override public Double apply(Tuple2<Double> data) { 
        return data.Val_1 + data.Val_2; 
       } 
      }).build(); 
    System.out.println(op.get("+").apply(new Tuple2<Double>(3d, 4d))); 

ich so etwas schreiben wollen:

ImmutableMap<String, Function<Double[], Double>> op = new // 
    ImmutableMap.Builder<String, Function<Double[], Double>>() 
      .put("+", new Function<Double[], Double>() { 
       @Override 
       public Double apply(Double... data) { 
        return data[0] + data[1]; 
       } 
      }).build(); 
    System.out.println(op.get("+").apply(3d, 4d)); 

Hilfe wäre sehr nützlich, ty.

Edit: Problem gelöst, gestartet mit:

public interface T2Function<T> { 
    T apply(T Val_1, T Val_2); 
} 
+0

Sie können dies tun, indem Sie eine andere 'Funktion' aus Ihrer' Funktion.Anwendung' zurückgeben und diese dann auf das zweite Argument anwenden. 'Function.apply (a) .apply (b)'. Die "innere" Funktion würde "a" direkt verwenden und "b" als Parameter erhalten. Dies könnte für "n" -Parameter erweitert werden. Das würde Haskells Behandlung von Funktionen nachahmen, aber ich bin mir nicht sicher, was Sie daraus in Javaland gewinnen würden. – jpaugh

Antwort

14

Ich glaube, Sie besser dran wäre eine Schnittstelle Ihrer eigenen verwenden, etwa so:

public interface Operation { 
    double apply(double a, double b); 
} 

Guava des Function ist eine einzige Argumentfunktion und nicht wirklich geeignet für irgendwas Multi-Argument.

Eine andere Sache, mit der ich experimentiert habe, ist eine ReduceFunction<F, T>, die zufällig für so etwas verwendbar ist. Es ist für die Verwendung mit dem reduce oder fold Betrieb und sieht ungefähr so ​​aus:

public interface ReduceFunction<F, T> { 
    T apply(T a, F b); // I can't decide on good names for the parameters =(
} 

Auf diese Weise können Sie Dinge tun, wie

List<Double> doubles = ... 
Double sum = reduce(doubles, MathOps.add(), 0.0); 

wo MathOps.add() ein ReduceFunction<Double, Double> ist, das die offensichtliche Sache tut.

+0

@CollinD: Was ist reduzieren und falten? Ich verstehe es nicht. – Emil

+4

@Emil: Sie sind funktionale Programmierkonstrukte, auch bekannt als Funktionen höherer Ordnung. Ein Reduzieren reduziert im Allgemeinen eine Liste in einen einzelnen Wert, indem Elemente durch eine gelieferte Funktion kombiniert werden. Eine "Falte" ist ähnlich einer Reduzierungsoperation, außer dass sie mit einem Anfangswert gesetzt werden kann. Die Funktion, die an die "Falte" geliefert wird, kombiniert dann die Listenelemente und den gesetzten Wert. – gpampara

+0

@gpampara: Wird eine solche funktionale Programmierung mit einer API durchgeführt? – Emil

3

Es sieht aus wie Sie nach einem Äquivalent zu C# Func: Spezialisiert in Ihrem Fall mit den Argumenten und Rückgabewert des gleichen Typs.

Es gibt zwei weitere Fragen gute Antworten zu diesem ..

Wie einige andere Antworten andeuten, können Sie zwischen zwei Paradigmen hier in der Mitte stecken (OO und funktional), etwas, mit dem Sprachdesign wohl schneller aufholt als gute Praxis. Wenn Sie mit diesem trüben Wasser weitermachen möchten, können Sie versuchen functionaljava.

Weitere interessante Diskussion finden Sie unter Mixing object-oriented and functional programming.