2016-07-16 4 views
4

S'il vous plaît soyez gentils avec moi.Que faisaient les programmeurs Java avant Java 8 s'ils voulaient passer une fonction?

J'entends Java 8 introduit lambdas. Mais avant cela, si vous vouliez faire circuler une fonction, disons, comme argument, qu'avez-vous fait?

Une façon je peux penser est de créer une interface unique méthode comme ceci:

public interface ISingleMethodInterface 
{ 
    bool Really(int n); 
} 

public bool GimmeFunction(ISingleMethodInterface interface, int n) 
{ 
    return interface.Really(n); 
} 

Mais c'est une application très limitée des fonctions comme des citoyens de première classe parce que:

  1. Vous ne peut pas faire grand-chose d'autre que d'exécuter cette fonction ou de passer cet objet à une autre méthode. Avec les lambdas, vous pouvez composer. Par exemple vous pouvez nier que lambda comme ceci:

    public bool GimmeLambdaAndIWillComputeItsInverse(Func<int, bool> predicate, int n) 
    { 
        return !predicate(n); 
    } 
    
  2. Vous ne pouvez pas retourner lambdas ou leurs dérivés. Je veux dire, vous ne pouvez retourner ce même objet comme ceci:

    // I know Java doesn't have Tuples but let's forget that for now 
    public Tuple GimmeFunction(ISingleMethodInterface interface, int n) 
    { 
        return new Tuple { Item1 = interface, Item2 = n }; 
    } 
    

    Avec lambdas, vous pouvez retourner les dérivés comme ceci:

    public Func<int, bool> GetInverseFunction(Func<int, bool> predicate, int n) 
    { 
        return n => !predicate(n); 
    } 
    

Alors, qu'avez-vous fait si vous aviez besoin de faire quelque chose comme ça?

+3

Exactement ce que vous décrivez, objets de commande. Si vous deviez les imbriquer pour la composabilité, qu'il en soit ainsi. –

+0

C'est trop triste. Pauvre toi! :-) –

+0

@SotiriosDelimanolis Si vous voulez mettre cela comme réponse, je peux le marquer comme le bon. –

Répondre

3

On a simplement passé des instances d'interfaces fonctionnelles. Votre dénigrement de ce relatif à lambdas est un peu éteint car en Java, les lambdas sont littéralement des interfaces fonctionnelles. Donc, puisque l'un est mis en œuvre en termes de l'autre, ils ne sont ni plus forts que l'autre. La différence réside dans la façon dont la lisibilité de la source vous frappe.

+0

Merci. Je disais des choses de façon factuelle. Je n'étais pas vraiment facétieux à ce sujet. –

0

Retour en vous les temps anciens avant Java 8, nous avons dû utiliser le maladroit vieux anonymous class syntax pour ce genre de chose, conduisant à un code qui avait l'air quelque chose comme ceci:

object.gimmeFunction(new SingleMethodInterface(){ 
    @Override public bool really(int n){ 
     return n=="really".hashCode(); 
    } 
}); 

Parce que ce modèle était si commun (voir Comparator, Runnable, ActionListener), il a été décidé que la langue pourrait utiliser une syntaxe beaucoup plus propre pour elle, et ainsi en Java 8 nous a donné lambdas tourner le bloc méchant ci-dessus dans:

object.gimmeFunction(n->n=="really".hashCode()); 

Contribuant ainsi à préserver la santé mentale des programmeurs Java partout. Les deux sont fonctionnellement équivalents, mais le premier est plus flexible, tandis que le second est beaucoup plus agréable à regarder.

+0

Belle réponse. –

+0

Mais faux. Nous n'avions pas besoin de l'utiliser. C'était l'une des nombreuses possibilités, – EJP