A sudden question is that Kotlin lambda expressions are easier to write than Java lambda expressions. What exactly makes you feel that way? I want to organize my mind.
One of the ways to write anonymous functions. In Java, when defining an anonymous function, it was described as follows.
public class Main {
public static void main(String[] args) {
Runnable r = new Runnable(){
@Override
public void run() {
System.out.println("Hello lambda.");
}
};
r.run(); // Hello lambda.
}
}
From Java8, lambda expressions are supported, which makes it easier to express.
public class Main {
public static void main(String[] args) {
Runnable r = () -> { System.out.println("Hello lambda."); };
r.run();
}
}
On the other hand, this is expressed by Kotlin's lambda expression as follows.
public class Main {
fun main(args: Array<String>) {
val r = {print("Hello lambda")}
r()
}
}
Kotlin can be omitted if no argument is required for the lambda expression, and there are minor differences such as not requiring the ";" at the end of the line. It can be expressed in almost the same way.
Let's consider another example. Let's define a function calc that takes two numbers, applies a function that calculates them, and returns them. This time from Kotlin
public class Main {
fun main(args: Array<String>) {
val op = { a:Int, b:Int -> a+b}
calc(1,2,op) // 3
}
fun calc(a: Int, b: Int, op: (Int, Int) -> Int): Int {
return op(a, b)
}
}
You could write it in the same way as before.
So what if you want to define it the same way in Java?
. .. ... ....
You can use BiFunction, a functional interface.
import java.util.function.BiFunction;
public class Main {
public static void main(String[] args) {
BiFunction<Integer, Integer, Integer> op = (a, b) -> a+b;
calc(1, 2, op); // 3
}
public static Integer calc(Integer a, Integer b, BiFunction<Integer, Integer, Integer> op){
return op.apply(a,b);
}
}
However, I was able to implement Javadoc without looking at anything. Is not it? I couldn't implement it without looking it up. ..
Now let's implement something that takes three arguments and calculates. First from Kotlin.
public class Main {
fun main(args: Array<String>) {
val op = { a:Int, b:Int, c:Int -> a+b+c}
calc(1,2,3,op) // 6
}
fun calc(a: Int, b: Int, c: Int, op: (Int, Int, Int) -> Int): Int {
return op(a, b)
}
}
Compared to the previous time, the argument c has increased, but I was able to write it almost the same as last time.
So what about Java? Last time I used BiFunction for Java. So, I think you should use TriFunction with the same glue. But ... *** This is not provided in a standard package. *** ***
Therefore, you need to define the functional interface (TriFunction) yourself as shown in the example below.
public class Main {
public static void main(String[] args) {
TriFunction<Integer, Integer, Integer, Integer> op = (a, b, c) -> a+b+c;
calc(1, 2, 3, op); //6
}
public static Integer calc(Integer a, Integer b, Integer c, TriFunction<Integer, Integer, Integer, Integer> op){
return op.apply(a,b,c);
}
@FunctionalInterface
interface TriFunction<A, B, C, R>{
R apply(A a, B b, C c);
}
}
So far, we have compared with various examples. So let's summarize what's different.
I understand that the difference in ease of writing between Java and Kotlin lambda expressions is "whether the function can be treated as a first-class function".
First-class function (first-class function) [1] is the nature of a programming language that can treat a function as a first-class object, or such a function. That is. In that case, the function has a type called function type (en: Function type) in a typed language, and its value becomes a function object or the like. Specifically, it is a function that is generated when the program is executed, can be included in the data structure, and can be passed as an argument of another function or returned as a return value.
Quote: https://ja.wikipedia.org/wiki/%E7%AC%AC%E4%B8%80%E7%B4%9A%E9%96%A2%E6%95%B0
Kotlin functions are first-class functions, so you can define functions without the need for interfaces / classes in advance.
On the other hand, Java functions are not first-class functions, so they require interfaces or classes that cannot be handled by the functions themselves and can be used as containers. Therefore, in order to implement a function like this time, it is necessary to check the interface in the first place, or to define it by yourself if it is not prepared in the standard package.
I think this difference is the difference in the writing comfort of Lambda.
I created this article not to say that Java is bad, but to sort out the vague feelings of haze. After all, if you don't chew and organize yourself, your understanding will not deepen. I would like to keep this attitude in the future.
https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/lambdas.html https://qiita.com/sano1202/items/64593e8e981e8d6439d3
Recommended Posts