Home > Software design >  Java: Do lambda expressions have a unique use that cannot be replicated through something else?
Java: Do lambda expressions have a unique use that cannot be replicated through something else?

Time:11-30

I'm learning about lambda-expressions today, and so far, I haven't found their unique use. So I'm asking myself if they are more than just a handy little gadget, taken from functional languages.

What are Lambda-Expressions?

From what I've read, they can be used to instantiate anonymous classes, pass simple methods and filter elements in collections. For example:

List<Integer> list = List.of(1, 2, 3, 4, 5);
   for (int i : list)
      System.out.println(i);

...can be written as:

List<Integer> list = List.of(1, 2, 3, 4, 5);
list.forEach((i) -> {
   System.out.println(i);
});

But why should you do that? Everytime you write down a lambda-expression, you could just put only the raw expression there!

public class Test {
    @FunctionalInterface
    interface BoolOperation {
        boolean execute(boolean param1, boolean param2);
    }

    static void test(BoolOperation op, boolean param1, boolean param2) {
        System.out.println(op.execute(param1, param2));
    }

    public static void main(String[] args) {
        test((x, y) -> x && y, true, false);
        
        test((x, y) -> x || y, false, true);
        
        test((x, y) -> x == y, true, true);
    }
}

...does the same as:

public class Test {
    public static void main(String[] args) {
        System.out.println(true && false);
        System.out.println(false || true);
        System.out.println(true == true);
    }
}

and

public class Test {
    public static void main(String[] args) {
        Runnable r = () -> {
                System.out.println("Running.");
        };
    }   
}

... is not that much shorter/readable than:

public class Test {
    public static void main(String[] args) {
        Runnable r = new ThreadThingy();
    }   
}

class ThreadThingy implements Runnable {
    public void run() {
        System.out.println("Running.");
    }
}

Edit: I've read the Oracle-Docs, but they are very specific and do not highlight a general use.

CodePudding user response:

Granted, your example with the boolean expression can be easier written directly. But what if you want to create truth tables for different boolean expressions?

public class Test {
    @FunctionalInterface
    interface BoolOperation {
        boolean execute(boolean param1, boolean param2);
    }

    static void line(String s, BoolOperation op, boolean b1, boolean b2) {
        System.out.printf("%b %s %b = %b%n", b1, s, b2, op.execute(b1, b2));
    }

    static void table(String s, BoolOperation op) {
        System.out.println("Truth table for " s);
        line(s, op, false, false);
        line(s, op, false, true);
        line(s, op, true, false);
        line(s, op, true, true);
        System.out.println();
    }

    public static void main(String[] args) {
        table("AND", (x, y) -> x && y);
        table("OR", (x, y) -> x || y);
        table("XNOR", (x, y) -> x == y);
        table("XOR", (x, y) -> x != y);
        table("implies", (x, y) -> !x || y);
    }
}

You could still do that using anonymous classes for the various operations, but it would take much more "boilerplate" - code that needs to be written just to satisfy the compiler without adding any value.

For example, you could write the first table call like this:

    table("AND", new BoolOperation() {
        @Override
        public boolean execute(boolean param1, boolean param2) {
            return param1 && param2;
        }
    });

but you can't tell me that this more readable and easier to understand than

        table("AND", (x, y) -> x && y);

CodePudding user response:

If you're looking for the rationale for why Lambdas were added to the Java Language, a good place to start would be the documentation on the original JSR request here:

https://jcp.org/en/jsr/detail?id=335

  • Related