简体   繁体   中英

Using lambdas as methods of a class in Java

As the title says, I am looking to implement some very short methods of a class using lambdas, nothing unheard of.

Python can do it, C# can do it, and to some extent i believe even C++ can do it now.

But I am trying to do the same with a Java class with no success, I looked up anything that might answer this particular question with no luck. I would rather not cluster my application with 100 functional interfaces just to be able to use lambdas for the more trivial functions or methods as that would kind of defeat the purpose of writing less code.

Here is what I did try(obviously, none of them worked, the second one came close as it at least recognized the fact that a lambda was there:

import static java.lang.Math.*;

class Main {

    static double log = (double val, double base) -> Math.log(val) / Math.log(base); // First try. Python way.

    static double log = (val, base) -> Math.log(val) / Math.log(base); // Second try. Also inspired from the 
                                                                       // Python way, somewhat similarly to the
                                                                       // F# or haskell way.

    static double log(double val, double base) -> Math.log(val) / Math.log(base); // Third try. The C# way.

    public static void main(String[] argv){

        System.out.println(log(8,2));

    }
}

Does the type on the left-hand side look correct?

 static double log = (double val, double base) -> Math.log(val) / Math.log(base); 

Is the type of the right-hand side double ? It isn't. It looks like a function. So the type at the left-hand side should be a function too.

You don't have to declare a lot of interfaces, because a lot of them have already exist in the library.

I agree, DoubleBinaryOperator doesn't quite roll off the tongue, but this is what you're looking for:

DoubleBinaryOperator log = (val, base) -> Math.log(val) / Math.log(base);

A less optimal alternative, but easier to remember, could have been a BiFunction :

BiFunction<Double, Double, Double> log = (val, base) -> Math.log(val) / Math.log(base);

That is, a BiFunction is a function that takes 2 double parameters and returns a double . This is less optimal, because it needs to autobox the parameters and the return value.

And to actually call these functions, you cannot write simply log(...) , you need the appropriate method name as specified in the interface. The method name should be easy to find in any IDE, because functional interfaces have the benefit of having precisely one method (on top of the common standard ones).

There are a bunch of common functional interfaces you need to keep in mind, and then it becomes a lot easier. Off the top of my head, Function , Consumer , Supplier , as well as those specialized for primitive types, IntBinaryOperator , IntUnaryOperator , and so on.

This would be the equivalent in java:

DoubleBinaryOperator log = (val, base) -> Math.log(val) / Math.log(base);
System.out.println(log.applyAsDouble(8,2));

or you could extract it into a method:

public static double log(DoubleBinaryOperator doubleBinaryOperator, double val, double base){
       return  doubleBinaryOperator.applyAsDouble(val, base);
}

then do:

System.out.println(log((val, bas) -> Math.log(val) / Math.log(bas), 8, 2));

see the Package java.util.function for picking the most appropriate functional interface for the task at hand or define your own if necessary .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM