Java programs are made up of classes and methods. Whenever you execute a method, define a class and create an object with new. For an interface, define a tangible class that implements it. Lambda expressions are a notation for processing such interfaces.
//The interface on which the class is based
public interface AnyClass {
public String getToday(boolean isAdvent);
}
//Define a class
public class AnyParentClass implements AnyClass {
public String getToday(boolean isAdvent) {
return isAdvent ? "AdventCalendar Day 17" : "December 17, 2020";
}
}
public void execSample1() {
//When calling a method, be sure to new the defined class
AnyClass obj = new AnyParentClass();
System.out.println(obj.getToday(true));
}
If you use the defined class AnyParentClass only here, using an anonymous class makes it a little easier to define. You no longer need the implemented class name AnyParentClass.
public void execSample2() {
//Anonymous classes make it a little easier to define
AnyClass obj = new AnyClass() {
public String getToday(boolean isAdvent) {
return isAdvent ? "AdventCalendar Day 17" : "December 17, 2020";
}
};
System.out.println(obj.getToday(true));
}
But can't we make the description a little easier?
--The declaration tells you that the variable obj uses AnyClass. --The interface AnyClass defines only one method.
Then
――Isn't it okay if you don't write new AnyClass ()? --Since there is only one method to use, isn't it okay if you don't write getToday ()?
That's why the lambda expression simplifies the description. However, you must use the phrase "->" to indicate that it is a lambda expression.
public void execSample3() {
//Lambda is easier
AnyClass obj = (a) -> {return a ? "AdventCalendar Day 17" : "December 17, 2020";};
System.out.println(obj.getToday(true));
}
In summary, the lambda expression is ** A notation that simplifies the definition when an interface with only one method is used as an anonymous class. ** ** Will be.
In this way, the lambda expression is a notation that omits the part "Isn't it okay if I don't write it?" I feel that the above code has a little more "Isn't it okay if I don't write it?"
――Since there is only one argument, isn't it okay if you don't write the argument ()? ――Since the process is one line, isn't it okay if you don't write {} or;? --Since the process is a method with only one line and a return value, isn't it okay if you don't write return?
Therefore, it can be omitted up to this point depending on the processing content.
public void execSample4() {
//Lambda expression easier
AnyClass obj = a -> a ? "AdventCalendar Day 17" : "December 17, 2020";
System.out.println(obj.getToday(true));
}
Besides making the definition easier, it has the following features.
As mentioned earlier, Java programs are made up of classes and methods. Therefore, in the usual notation, the object with the new class is stored in the variable, but the lambda expression seems to store the process directly, so it is easy to imagine the contents of the variable.
public void execSample5() {
//Assign an object to a variable, this is usually
AnyClass obj1 = new AnyParentClass();
//Lambda expressions appear to assign processing (functions) directly to variables
AnyClass obj2 = (a) -> {return a ? "AdventCalendar Day 17" : "December 17, 2020";};
}
The sample code so far has defined the AnyClass interface. AnyClass is an interface with one method, one argument, and a return value, which is common. So this is also "Isn't it okay if I don't define it?" Yes, an interface called Function is already defined in Java and you can use it.
public void execSample6() {
//No need for AnyClass, use function of existing interface
Function<Boolean, String> obj = a -> a ? "AdventCalendar Day 17" : "December 17, 2020";
System.out.println(obj.apply(true));
}
The interfaces already defined are in java.util.function, for example:
--Function \ <T, R> There is one argument and there is a return value
--Consumer \
Stream API The Stream API shouldn't be difficult, just like StringBuilder # append (). Because append () uses StringBuilder as the return value StringBuilder.append(xxx).append(xxx).append(xxx) ... Can be connected with.
Similarly, the Stream API has a method in which the Stream class (more precisely, the interface) returns Stream. So you can concatenate methods like StringBuilder # append (), but Stream's method allows you to specify a lambda expression as an argument and can concatenate with processing included.
public void execSample7() {
List<String> list = Arrays.asList("A","D","V","E","N","T"," ","C","A","L","E","N","D","A","R");
//Execution result "A! C! D! E! 」
list.stream().filter((s) -> { return "ABCDE".indexOf(s) != -1; }) //→ Returns Stream
.sorted((s1, s2) -> { return s1.compareTo(s2); }) //→ Returns Stream
.map((s) -> { return s + "!"; }) //→ Returns Stream
.distinct() //→ Returns Stream
.forEach((s) -> { System.out.print(s + " "); });
}
(*) This article was written for the purpose of first understanding the lambda expression by beginners. There may be expressions that deviate from the essential ideas due to my lack of study, but please forgive me.
Recommended Posts