Home  >  Article  >  Java  >  How to use lambda expressions in Java8

How to use lambda expressions in Java8

黄舟
黄舟Original
2017-09-19 10:34:581250browse

The most worth learning feature of Java8 is Lambda expressions. The following article mainly introduces to you the relevant information about the use of lambda expressions in the Java8 learning tutorial. The article introduces it in great detail through sample code. It is very useful for everyone's learning or The work has a certain reference and learning value. Friends who need it can follow the editor to learn together.

Preface

We introduced the syntax of lambda expressions in the previous article, introduced the usage scenarios of lambda expressions, and Benefits of using lambda expressions. In this article, we will explain with examples how to define and use lambda expressions, as well as the special specifications of lambda expressions in Java compared to other languages.

Examples of using anonymous inner classes

First of all, let’s make it clear that before the advent of Java8, lambda expressions could be done using inner classes It can be done, lambda expressions just simplify programming.
The following example selects readers from the list based on conditions.

Define TantanitReader:


public class TantanitReader {
 private int age;
 private String loginName;
 private String realName;
 private String career;

 public TantanitReader() {
 }

 public TantanitReader(int age, String loginName, String realName, String career) {
 this.age = age;
 this.loginName = loginName;
 this.realName = realName;
 this.career = career;
 }

 public int getAge() {
 return age;
 }

 public void setAge(int age) {
 this.age = age;
 }

 public String getLoginName() {
 return loginName;
 }

 public void setLoginName(String loginName) {
 this.loginName = loginName;
 }

 public String getRealName() {
 return realName;
 }

 public void setRealName(String realName) {
 this.realName = realName;
 }

 public String getCareer() {
 return career;
 }

 public void setCareer(String career) {
 this.career = career;
 }

 @Override
 public String toString() {
 return "age:"+this.getAge()+",loginName:"+this.loginName
 +",realName:"+this.getRealName()+",career:"+this.getCareer();
 }
}

Define the judgment interface:


public interface Predicate<T> {
 boolean test(T t);
}

Define the selection function:


public class SelectService<T> {
 public List<T> select(Collection<T> source, Predicate<T> predicate){
 List result = new LinkedList();
 for(T element:source){
  if (predicate.test(element)) {
  result.add(element);
  }
 }
 return result;
 }

}

Writing examples for testing, selecting adult readers and readers in their teens (including 10 years old):


public class TantanitReaderPredicateTest {


 public static void main(String[] args) {
 SelectService tantanitReaderSelectSerive
 =new SelectService<TantanitReader>();
 List<TantanitReader> source = new LinkedList<>();
 source.add(new TantanitReader(10,"jack","张三","学生"));
 source.add(new TantanitReader(18,"rose","李四","学生"));
 source.add(new TantanitReader(19,"mike","王五","程序员"));
 source.add(new TantanitReader(20,"jack","赵六","作家"));

 List<TantanitReader> audultReaders
 =tantanitReaderSelectSerive.select(source, new Predicate() {
  @Override
  public boolean test(Object o) {
  TantanitReader tantanitReader=(TantanitReader)o;
  return tantanitReader.getAge()>=18;
  }
 });
 System.out.println("tantanit.com 成年读者名单如下:");
 printTantanitReaders(audultReaders);

 System.out.println("tantanit.com 十多岁(包含 10 岁)成员如下:");
 List<TantanitReader> teenReaders
 =tantanitReaderSelectSerive.select(source, new Predicate() {
  @Override
  public boolean test(Object o) {
  TantanitReader tantanitReader=(TantanitReader)o;
  return tantanitReader.getAge()>=10 && tantanitReader.getAge()<=19;
  }
 });
 printTantanitReaders(teenReaders);
 }


 public static void printTantanitReaders(List<TantanitReader> tantanitReaders) {
 for (TantanitReader tantanitReader : tantanitReaders) {
  System.out.println(tantanitReader.toString());
 }
 }


}

After execution, the print result is as follows:


tantanit.com 成员读者名单如下:
age:18,loginName:rose,realName: 李四,career: 学生 
age:19,loginName:mike,realName: 王五,career: 程序员
age:20,loginName:jack,realName: 赵六,career: 作家
tantanit.com 十多岁(包含10 岁)成员如下:
age:10,loginName:jack,realName: 张三,career: 学生
age:18,loginName:rose,realName: 李四,career: 学生
age:19,loginName:mike,realName: 王五,career: 程序员

It can be seen that new Predicate() is required for selecting readers twice, and Override the test method, and the real difference is actually only in the judgment statement:


tantanitReader.getAge()>=18

and


tantanitReader.getAge()>=10 && tantanitReader.getAge()<=19

But before Java8, since there were no lambda expressions, we could only tolerate this redundancy. How to use lambda expressions to simplify code?

In order to take care of the existing programming habits of Java developers, unlike other languages, when designing the usage mechanism of lambda expressions, Java8 stipulates that interfaces still need to be used, and the interface used must be a functional interface. , in this example, we can still use:


public interface Predicate<T> {
 boolean test(T t);
}

Because this interface has only one abstract method (java8 introduced the default method, the default method has a specific implementation and is not considered abstract method), so it is a functional interface. Functional interfaces can be declared with @FunctionalInterface or not. But after adding it, the compiler will check whether the interface conforms to the definition of a functional interface during the compilation phase, so here we define a new interface and add the @FunctionalInterface declaration:


@FunctionalInterface
public interface PredicateFunction<T> {
 boolean test(T t);
}

And add a method with PredicateFunction as parameter to SelectService:


public List<T> select(Collection<T> source, PredicateFunction<T> predicate){
 List result = new LinkedList();
 for(T element:source){
 if (predicate.test(element)) {
  result.add(element);
 }
 }
 return result;
}

Then modify the test example:


public class TantanitReaderPredicateFunctionTest {

 public static void main(String[] args) {
 SelectService tantanitReaderSelectSerive
 =new SelectService();
 List source = new LinkedList<>();
 source.add(new TantanitReader(10,"jack","张三","学生"));
 source.add(new TantanitReader(18,"rose","李四","学生"));
 source.add(new TantanitReader(19,"mike","王五","程序员"));
 source.add(new TantanitReader(20,"jack","赵六","作家"));

 PredicateFunction predicateFunction
  = (TantanitReader tantanitReader) -> tantanitReader.getAge() >= 18;
 List audultReaders
 =tantanitReaderSelectSerive.select(source,predicateFunction);

 System.out.println("tantanit.com 成员读者名单如下:");
 printTantanitReaders(audultReaders);

 System.out.println("tantanit.com 十多岁(包含 10 岁)成员如下:");
 PredicateFunction predicateFunction2
 = (TantanitReader tantanitReader)
 -> tantanitReader.getAge()>=10 && tantanitReader.getAge()<=19;
 List teenReaders
 =tantanitReaderSelectSerive.select(source,predicateFunction2);
 printTantanitReaders(teenReaders);
 }


 public static void printTantanitReaders(List tantanitReaders) {
 for (TantanitReader tantanitReader : tantanitReaders) {
  System.out.println(tantanitReader.toString());
 }
 }

}

Let's analyze how this code takes effect:


PredicateFunction<TantanitReader> predicateFunction
 = (TantanitReader tantanitReader) -> tantanitReader.getAge() >= 18;
List<TantanitReader> audultReaders
=tantanitReaderSelectSerive.select(source,predicateFunction);

This code generates an instance of the PredicateFunction type and changes the instance's Reference the select method passed as a parameter to tantanitReaderSelectSerive, and execute the select method. During the execution of select, the test method of predicateFunction is called, and the content of the test method is the lambda expression we passed in. Finally, the reader is selected according to the lambda expression.

Going further, you can generally not define the predicateFunction variable, but directly pass the lambda expression as a parameter to the select method of tantanitReaderSelectSerive, like this:


List<TantanitReader> audultReaders
=tantanitReaderSelectSerive.select(
 source,(TantanitReader tantanitReader) -> tantanitReader.getAge() >= 18
);

But in this example, a compilation error will actually be reported, saying that the definitions of the select methods of TantanitReader and tantanitReaderSelectSerive do not match, because the select method uses generics. The Java 8 documentation does stipulate that when using generics, lambda expressions cannot be used directly as parameters. This is quite embarrassing. If you don't use generics, there won't be this problem.

Summary

The following is a summary of how to use lambda expressions

  • First, define a function Functional interface, and define the abstract methods to be used in the interface.

  • Write a business method, take the functional interface as a parameter, and call the method defined by the interface to complete the business logic.

  • Call the business method and pass in the lambda expression as a parameter.

If generics are used, the last step is to first define a reference to an instance of the functional interface and then pass it to the business method as a parameter.

In addition, lambda expressions can continue to be simplified into function references, which will be explained in a later article.

Summarize

The above is the detailed content of How to use lambda expressions in Java8. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn