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: