2016-04-19 1 views
0

J'ai un lambdaCombinaison de lambdas en Java?

(a, b) -> { 
    a.doSomething(); 
    a.doAnotherThing(); 
    return b.doSomething(); 
} 

En ce moment, ce juste se sert comme paramètre dans une seule méthode. Cependant, je voudrais également créer un lambda similaire

(a) -> { 
    a.doSomething(); 
    a.doAnotherThing(); 
    return a 
} 

Y at-il un moyen de réutiliser mon code? Quelque chose comme

(a, b) -> { 
    partial(a) 
    return b.doSomething(); 
} 

(a) -> { 
    partial(a) 
    return a; 
} 
+1

Sure. Qu'est-ce qui t'arrête? –

+0

... Je ne sais pas comment? Je ne sais pas à quoi ressemblerait le bon code – Andrew

+0

Cela ressemblerait exactement à ce que vous avez déjà suggéré. Écrivez simplement une méthode 'partial (a)'. –

Répondre

0

Si j'ai bien compris, vous voulez appeler un lambda d'un autre lambda?

Vous pouvez leur donner un nom et de les utiliser comme toute autre fonction

Function<X,Y> partial = (a) -> { 
    a.doSomething(); 
    a.doAnotherThing(); 
    return a; 
} 

BiFunction<X,Y,Z> lam = (a, b) -> { 
    partial.apply(a); 
    return b.doSomething(); 
} 
+0

Type de 'lam' devrait être 'BiFunction '. – saka1029

+0

Oups, merci! édité –

+0

'partial (a)' -> 'partial.apply (a)'. – saka1029

0

Je suppose que votre utilisation de partial ici ne se réfère pas à la notion de programmation fonctionnelle des fonctions partielles.

En regardant vos exemples, les opérations sur a prises ensemble sont juste un consommateur car elles ne renvoient aucune valeur. Votre lambda réutilisable pourrait être déclarée comme ceci:

Consumer<A> partial = a -> { 
    a.doSomething(); 
    a.doAnotherThing(); 
} 

Pour composer une fonction qui appelle d'abord un consommateur, vous pouvez garder cette aide à portée de main:

static <T,U,R> BiFunction<T,U,R> acceptAndThen(Consumer<T> c, Function<U,R> f){ 
    return (t,u) -> { 
     c.accept(t); 
     return f.apply(u); 
    }; 
} 

que vous pouvez utiliser pour composer une fonction équivalente à votre fonction originale comme celui-ci (je ne sais pas le type de retour de b.doSomething(), je suppose que C):

BiFunction<A,B,C> f1 = acceptAndThen(partial, B::doSomething); // equivalent to (a, b) -> { partial.accept(a); return b.doSomething(); } 

votre deuxième exemple, qui montre comment vous pouvez réutiliser partial d'une manière différente, pourraient bénéficier d'une autre aide qui convertit un Consumer<T> à un Function<T,T> en retournant le T que le Consumer<T> opéré sur:

static <T> Function<T,T> returnSelf(Consumer<T> consumer){ 
    return t -> { 
     consumer.accept(t); 
     return t; 
    }; 
} 

Ainsi, vous pouvez créer votre deuxième exemple comme ceci:

Function<A,A> f2 = returnSelf(partial); // equivalent to (a) -> { partial.accept(a); return a; } 

Ces compositions ne sont pas dans la bibliothèque standard, mais vous trouverez que des interfaces comme Consumer et Function ont des fonctions intégrées pour composer des types fonctionnels existants dans de nouveaux. Par exemple, Consumer a une fonction, andThen qui peut enchaîner les consommateurs à appeler en séquence. En utilisant que votre partiel aurait pu ressembler à

Consumer<A> partial = ((Consumer<A>) A::doSomething).andThen(A::doAnotherThing);