It's been a little over two years since I jumped into the IT industry. To be honest, I've been working on coding in earnest for only a little over a year. At the same time, because of operation and maintenance, it has lived in a positive world to enhance existing implementations so as not to pollute them as much as possible. And after all, the JDK used in that package is java 1.7! !! From the above background, I rarely touched on java8 or later, so I wanted to relearn it again. While also serving as a memorandum, I would like to start writing for Qiita in earnest in the future, so I decided to write this time.
As a first step, my understanding of lambda expressions was vague, so I would like to deepen my understanding through the article.
Before we can understand lambda expressions suddenly, it seems that we need some prerequisite knowledge about functional interfaces. Then what is an interface in the first place? I can't answer clearly when asked. Don't be afraid to get a solid understanding of Java's interfaces.
I think the following articles are easy to understand and helpful. https://www.internetacademy.jp/it/programming/java/difference-between-interface-and-abstract.html
An interface prepares only a method box, and when the box is actually used (inheritance), the inherited class is forced to implement it.
For example, consider a situation where ʻEmployeeService is implemented as a Service class for an Entity called ʻEmployee
.
EmployeeService.java
interface EmployeeService {
Employee getEmployee(String pk);
}
A common (used case) implementation of the Service class is to implement the Service interface and expose only the methods to the outside world.
Create ʻEmployeeServiceImpl as another class as an implementation class of ʻEmployeeService
.
EmployeeServiceImpl.java
public class EmployeeServiceImpl implements EmployeeService {
Employee getEmployee(String pk) {
//Go to Dao and get the Employee that matches pk.
return employeeDao.find(pk);
}
}
The important thing here is that this ʻEmployeeServiceImpl inherits from ʻEmployeeService
, so
It means that you must implement getEmployee
declared in ʻEmployeeService`.
By doing this, the implementation class that inherits the interface must implement the method declared in the interface, resulting in a compile error, and the implementation can be forced.
The biggest difference between abstract classes and interfaces is that they can be inherited multiple times. I won't go into details about multiple inheritance, but the point is that an interface can use a mechanism that forces multiple implementations. (One class can inherit multiple interfaces.)
I understand the interface. I understand, but I still have enough knowledge to understand lambda expressions.
What is a functional interface?
Hmm, what is a functional
?
Hmm, what is a function
?
The following URL will be helpful for what a function is. https://stackoverflow.com/questions/155609/whats-the-difference-between-a-method-and-a-function
In short, a function is `A parameter (argument) that is received, some processing is added based on the argument, and the resulting value is returned (return). ``
There are some points to keep in mind when implementing a function, so I will introduce it here.
If you're programming in a language like Java, you'll sooner or later hear the word side effects
.
Side effects are super easy to say roughly ...
I understand that it is an implementation in which the execution result of a function is not always constant.
Here are some things to keep in mind to implement a function that has no side effects:
Please check the specific implementation examples separately. (There are 50,000 articles that explain better than me.)
Returning to the story, a function is, after all, a value that returns a value for an input.
I got a rough idea of the functions. So what is a functional interface? Let's move the subject to the story. The following article is quite helpful, so I will describe it. http://www.ne.jp/asahi/hishidama/home/tech/java/functionalinterface.html#h_outline
As mentioned in this article, what is a functional interface?
An interface with only one abstract method defined.
about it.
The ʻEmployee Serviceintroduced in this article can be called a functional interface. A
Service class that only fetches and returns ʻEmployee
that matches pk
.
EmployeeService.java
@FunctionalInterface
public interface EmployeeService {
Employee getEmployee(String pk);
}
The key to defining a functional interface is the @FunctionalInterface
annotation.
By adding this annotation, it is possible to explicitly declare that it is a functional interface, and an error will occur if the conditions are not met even at compile time.
In addition, by adding this annotation even when following the implementation, it becomes easier for others to understand that it is a functional interface.
default
and static
methods are defined, they seem to be excluded from the conditions of functional interface.Starting with JDK1.8, functional interfaces (interfaces that hold only one abstract method) are treated as special. Well, I've finally returned to the main topic of this article. What is the lambda expression after all from here? I will try to find out.
The following article is very easy to understand and is helpful because it illustrates the lambda expression. http://masatoshitada.hatenadiary.jp/entry/2015/02/09/190150
After all, I think the best way to understand lambda expressions is to understand type inference
using Function
as an example.
Function is a package introduced in Java 8.
The type is defined by Function <T, R>
, T
is the argument type, and R
is the return type.
So, this Function
is defined as a functional interface and has only a method called ʻapply`.
You can use a lambda expression to implement a Function
.
A simple implementation example is shown below.
Example) Get the Name
of ʻEmployee using
Function`.
Employee.java
@Getter
@Setter
@AllArgsConstructor(staticName = "of")
public class Employee {
/** Id */
private int id;
/** Name */
private String name;
}
Main.java
pubic class Main {
public static void main(String args[]){
Employee emp = Employee.of(1, "Sample Taro")
Function<Employee, String> getEmployeeName = employee -> employee.getName();
String empName = getEmployeeName.apply(emp);
System.out.println(empName); //"Sample Taro" is output.
}
}
Getter
if you take out Name
.Here is the important point in the above example.
Function<Employee, String> getEmployeeName = employee -> employee.getName();
Function
has the process of returning the string type (String
) which is the result of ʻemployee.getName () as the return value from the type (ʻEmployee
) which is the argument of Function
. Implement it in a method called ʻapply`.
That is done using a lambda expression.
Java interprets that ʻemployee is
Tin
type inference as ʻEmployee
, and Java interprets that the value return
in type inference
is String
. (It's smart ...)
String empName = getEmployeeName.apply(emp);
And actually, in the above part, apply apply
of Function
to ʻempName` of String.
Lambda expressions have the advantage of simplifying the description of functional interfaces.
After all, the lambda expression that I understood is a convenient one that makes full use of type inference to simplify the implementation when implementing a functional interface.
The usage scenes of the lambda expression alone are limited, and I wonder if the lambda expression really shows its full potential when combined with Function
and stream
.
It's not always necessary to be aware of this lambda expression when using stream
, but it's worth understanding.
I'm thinking of relearning ʻOptional, but it seems that lambda expressions (or rather
Consumer`) are involved.
Writing an article will improve your understanding + it will be a reminder, so I would like to continue writing actively in the future.
If you have any mistakes or advice, please leave a comment ...!
Next time, I would like to write an article about ʻOptional`. See you soon~
Recommended Posts