Explain Java 8 lambda expressions

0. Table of contents

1.First of all 2. Understand the interface and its features to understand lambda expressions 3. How to use lambda expression 4. Conclusion

1.First of all

Hello. This is an article about lambda expressions newly added in Java 8.

By the way, the other day I got the Oracle certification Java SE8 Silver. Among them, there was a time when I mentioned the lambda expression added from Java 8. I got the impression that I couldn't understand it just by reading it in a book.

And even if I searched for and read an article about lambda expression on Qiita, what is written after all Because the contents of the reference book that is difficult to understand and what is written in the Java API are the same I thought few people really understood the benefits of lambda expressions.

So, this time, rather than what the lambda expression is, how to use the lambda expression. I wanted to write an article about its benefits.

That's why I will explain about lambda expressions from the next chapter, Before that, you need to understand the interface and its features once in order to understand lambda expressions.

2. Understand the interface and its features to understand lambda expressions

Many articles written about lambda expressions are not clear to the author of the article.

  1. People who don't understand the interface properly have only lambda specifications.
  2. Without touching on the premise of lambda expressions called interfaces, I suddenly explain what lambda expressions are.

I think it's because someone who fits into one of the above. So, in this article, I will first describe two points about the features of the interface and its advantages. It's about polymorphism and encapsulation.

Then the first point. About polymorphism.

By the way, what is an interface in Java? "* Defines only the types of variables and methods without describing the specific processing contents of the methods included in the class * * 1" is not it.

This alone does not come to a pin, so I will put a sample source.

PrintoutMessage.java



package sample;

public interface PrintoutMessage {

	public void printSomeMessage(String message);

}

In the above sample source PrintoutMessage.java, there is a method called printSomeMessage and Only the argument type and variable name are defined. In this way, a method like printSomeMessage that defines only the method and its argument types and variable names Called an * abstract method . ( 2)

At this point, no processing is defined in the method called printSomeMessage, so You can't do anything with this method alone.

However, by implementing the interface in a class, you can write the process in that method. This also doesn't work, so check the sample code.

ConcretePrintMessage_Hello.java



package sample:ConcretePrintMessage_Hello.java

/* 1.Implement interface*/
public class ConcretePrintMessage_Hello implements PrintoutMessage {

	@Override
	/* 2.Represent the method of the implemented interface*/
	public void printSomeMessage(String message) {

		/* do some process */
		/* do some process */
		/* do some process */
		/* do some process */
		System.out.println(message + "Hello");

	}

	public static void main(String[] args) {

		/* 3.Instantiation*/
		ConcretePrintMessage_Hello p = new ConcretePrintMessage_Hello();

		/* 4.Call the method*/
		p.printSomeMessage("Welcome to Qiita,");

	}

}

In ConcretePrintMessage_Hello.java above, by implementing the interface, The printSomeMessage method is made to display "message + Hello received as an argument". This time, I wrote only one line (System.out.println ();) for the sake of explanation. It is possible to have multiple processes as shown in the comments on the source. (* 3)

Up to this point, it has been found that the interface can be used by implementing the interface in a class, redefining the method in the implemented class (* 4), and describing the processing content.

However, with this alone, it would be "Why do you bother to use the interface? You should create the printSomeMessage method with ConcretePrintMessage_Hello.java without defining the interface?"

Let's take a look at another sample code to solve such a question.

ConcretePrintMessage_Goodbye.java


package sample;

/* 1.Implement interface*/
public class ConcretePrintMessage_Goodbye implements PrintoutMessage {

	@Override
	/* 2.Represent the method of the implemented interface*/
	public void printSomeMessage(String message) {

		/* do some process */
		/* do some process */
		/* do some process */
		/* do some process */
		System.out.println(message + "Goodbye");

	}

	public static void main(String[] args) {

		/* 3.Instantiation*/
		ConcretePrintMessage_Goodbye p = new ConcretePrintMessage_Goodbye();

		/* 4.Call the method*/
		p.printSomeMessage("See you again,");


	}

}

This time, ConcretePrintMessage_Goodbye.java is used to display "message + Goodbye received as an argument" in the printSomeMessage method. There is only one difference from the previous ConcretePrintMessage_Hello.java. Whether to display "message + Hello received as an argument" or "message + Goodbye received as an argument".

Both have the same method name, printSomeMessage (String message) ;, but the same argument type and argument name, but the processing content is different. Have you heard of this?

Yes, this is "* polymorphism *". The benefits of polymorphism are not discussed here, but what we have learned so far is what an interface is. It's a way to achieve polymorphism. You can easily achieve polymorphism by defining an interface and implementing it. This is the first feature and advantage of the interface.

Next is the second point, encapsulation.

Now, I would like to add one method to ConcretePrintMessage_Goodbye.java.

ConcretePrintMessage_Goodbye.java


package sample;

/* 1.Implement interface*/
public class ConcretePrintMessage_Goodbye implements PrintoutMessage {

	@Override
	/* 2.Represent the method of the implemented interface*/
	public void printSomeMessage(String message) {

		/* do some process */
		/* do some process */
		/* do some process */
		/* do some process */
		System.out.println(message + "Goodbye");

	}

	public static void main(String[] args) {

		/* 3.Instantiation*/
		ConcretePrintMessage_Goodbye p = new ConcretePrintMessage_Goodbye();

		/* 4.Call the method*/
		p.printSomeMessage("See you again " + p.getMyName() + ", ");


	}

	/*Added method*/
	private String getMyName() {

		return "Tom";

	}

}

The method added to ConcretePrintMessage_Goodbye.java is the getter getMyName () to get the name. The access modifier for this method is private, isn't it? Methods with the private modifier can only be referenced from the same class. Therefore, if you want to process only with that class, specify private as the access modifier. All you have to do is make it inaccessible from other classes. In this example, getting the name Tom by getMyName () is private because we want to do it only with ConcretePrintMessage_Goodbye.java.

On the other hand, the modifier of the method implemented in the interface is always public, so it can be accessed from all classes. Therefore, the abstract method defined in the interface can be used to implement what you want to process in common in all classes according to the class. Moreover, the method name used for the common process must be the same as the one defined in the interface. No matter who wrote the source, as long as you implement the interface, with a method of the same name Since common processing is performed, you can roughly imagine what it is doing at a glance.

This is encapsulation, and I've found that the interface helps to create the methods I want to access from all classes in doing the encapsulation.

These are the features of the interface and its advantages. (* 6)

3. How to use lambda expression

So far, we know that the interface has the advantages of polymorphism and encapsulation, It feels like what the lambda expression has to do with it. To explain that, let's look at how to use the interface again. The sample source below is the same as the sample source above.

ConcretePrintMessage_Hello.java



package sample;

/* 1.Implement interface*/
public class ConcretePrintMessage_Hello implements PrintoutMessage {

	@Override
	/* 2.Represent the method of the implemented interface*/
	public void printSomeMessage(String message) {

		/* do some process */
		/* do some process */
		/* do some process */
		/* do some process */
		System.out.println(message + "Hello");

	}

	public static void main(String[] args) {

		/* 3.Instantiation*/
		ConcretePrintMessage_Hello p = new ConcretePrintMessage_Hello();

		/* 4.Call the method*/
		p.printSomeMessage("Welcome to Qiita,");

	}

}

From the beginning I've been writing steps to use the interface for comments on the source, Isn't it annoying to take these four steps every time? (Lol) In an actual project, I write this for about 100 classes every time, so It's annoying to write this every time for 100 classes, even though the interface has its advantages.

Therefore, the lambda expression was born as a result of thinking "Isn't it easier to use the interface?"

… To put it bluntly, that's all for the lambda expression.

Let's check the sample code to see how easy it is to handle the interface!

ConcretePrintMessage_GoodMorning.java


package sample;

public class ConcretePrintMessage_GoodMorning {

	public static void main(String[] args) {

		PrintoutMessage p = (String message) -> {

			/* do some process */
			/* do some process */
			/* do some process */
			/* do some process */
			System.out.println(message + "GoodMorning!!");

		};

		p.printSomeMessage("How's your sleep? ");

	}

}

The procedure is considerably simplified compared to the previous source.

  1. Implement the interface
  2. Represent the method of the implemented interface
  3. Instantiation

All you have to do is describe the processing content and call the method. The rest only mentions the specifications for lambda expressions that are commonplace in many places. If you look at the article, the lambda expression should be perfect. Especially for lambda expressions, to deal with the "functional interface" that I mentioned a little in this article. There are many specifications, so it is recommended to take a look around them.

4. Conclusion

Thank you for reading until the end. If you have any suggestions or questions, please leave a comment.


Recommended Posts

Explain Java 8 lambda expressions
Understand Java 8 lambda expressions
About Java lambda expressions
[Java] Introduction to lambda expressions
Java lambda expressions learned with Comparator
[Introduction to Java] About lambda expressions
Getting started with Java lambda expressions
The origin of Java lambda expressions
How to use Java lambda expressions
Hello Java Lambda
[Java] Lambda expression
Java lambda expression
I tried to summarize Java lambda expressions
Nowadays Java lambda expressions and Stream API
java neutral lambda expression 1
[Java] Summary of how to abbreviate lambda expressions
Quarkus saves Java Lambda! ??
Java 8 lambda expression Feature
java lambda expression memo
Java lambda expression [memo]
Studying Java 8 (lambda expression)
Review java8 ~ Lambda expression ~
Java lambda expression again
Java Lambda Command Pattern
[Java Silver] Summary of points related to lambda expressions
[Java] Sort the list using streams and lambda expressions
Use Java lambda expressions outside of the Stream API
Use Lambda Layers with Java
[Java] Functional interface / lambda expression
Java8 stream, lambda expression summary
Java (Kotlin / JVM) lambda expressions are not always separate instances
Handle exceptions coolly with Java 8 lambda expressions and Stream API
Rethinking design patterns with Java8 lambda expressions & Stream --Builder pattern -
About C # lambda expressions and Linq
[Java] Can you explain this phenomenon?
Java for beginners, expressions and operators 1
About Lambda, Stream, LocalDate of Java8
Is Java on AWS Lambda slow?
Hello World on AWS Lambda + Java
Java for beginners, expressions and operators 2
Java
What is a lambda expression (Java)
Java
A little understanding of lambda expressions
Name a group of regular expressions (Java)
Implement API Gateway Lambda Authorizer in Java Lambda
Now let's recap the Java lambda expression
[Java] for Each and sorted in Lambda
AWS Lambda with Java starting now Part 1
Until programming beginners can use lambda expressions
Working with huge JSON in Java Lambda
Easy to trip with Java regular expressions
Organize your own differences in writing comfort between Java lambda expressions and Kotlin lambda expressions.