preface

Java13 is already here, and many of you are still stuck with java5. If you don’t use some of the new java8 features in your daily development or won’t use them. This article may be of help to you.

Lambda expressions

introduce

Lambda expressions are a new syntax in java8 that makes code more elegant by making anonymous calls.

Functional interface

introduce

To make lambda expressions more user-friendly, the concept of a functional interface was introduced in java8.

  • A “functional interface” is an interface that contains only one abstract method, but can have multiple non-abstract methods (the default method modification).
  • “Functional interfaces” can be used@FunctionalInterfaceAnnotations are declared on the interface. So every interface you see with this annotation on it is a functional interface.

Use lambda expressions in functional interfaces

Let’s start with the following code

    @Test
    public void FunctionalInterface(){

        new Thread(new Runnable() {
            @Override
            public void run() {
                print();
            }
        });

        new Thread(
            () ->{print(a); }); new Thread(() ->print());

        new Thread(this::print);
    }

    public void print(){
        System.out.println("hello domain");
    }
Copy the code

The Runnable interface above is a functional interface. The first way to create an instance of an interface is to create a traditional anonymous inner class. The remaining three are interface instances created using lambda. There’s nothing to say about the first one, but a few grammatical explanations for the other three.

  1. The first syntax format is plain full lambda syntax, in the form:() - > {}The parentheses are the arguments to the interface method, and the parentheses are the logic to the method. Think of it in contrast to the anonymous implementation of the interface.
  2. The second way is to omit the braces when the code inside the braces is a single line of code.
  3. The third way is called a lambda method reference, where the curly braces are gone, and only the method reference is left. The reason for this is that the method calls in curly braces are the same as the method calls in curly braces. In the example, both the parentheses and the methods called in the braces have no arguments. If they have arguments, they look like this:
    @Test
    public void testFunctionalInterface(){
        WebService webService = this::print;
        webService.sayHi("domain");
    }

    public void print(String str){
        System.out.println("hi:"+str);
    }
Copy the code

Two points can be seen in the above example. The first is the lambda practice with arguments mentioned above, and the second is that the lambda expression returns an implementation instance of the interface.

Method references

Method references can be made in three ways: class name :: method, object :: method, class name ::new, and the last syntax is the constructor of the reference.

Stream

introduce

Stream is a new JAVa8 API for collections (excluding maps) that works with Lambda to make it easier to manipulate collections.

use

Start by creating a list collection and manipulating it with stream.

    List<User> users = new ArrayList<>();
    users.add(new User("domain", 18)); users.add(new User("alex", 19)); users.add(new User("lily", 20)); users.add(new User("joy", 21));Copy the code

Filter (filter)

To filter the data in the set, use the filter method, for example, I want to get the people in the set who are older than 18:

        List<User> users = users.stream()
                .filter(new Predicate<User>() {
                    @Override
                    public boolean test(User user) {
                        return user.getAge() > 18;
                    }
                }).collect(Collectors.toList());
Copy the code

As you can see, the piece of anonymous internal implementation can be implemented using lambda expressions:

        List<User> users = users.stream()
                .filter(user -> user.getAge() > 18).collect(Collectors.toList());

Copy the code

User.stream to get steam objects, filter to filter, collect to generate filtered objects, because the original object does not change.

Type Conversion (MAP)

Change the set type and element if I want to get all the names in the set:

        users.stream()
                .filter((user) -> user.getAge() > 18)
                .map(User::getName)
                .forEach(System.out::println);
Copy the code

This prints all the names. The map can then be converted into a new collection object using the collect method just described. This is not done in the example, but rather each element is printed out by forEach.

Matching (match)

Find the elements in the collection and match them.

  • Any match

Now I want to know if there is a person with the name Domain in the set

       boolean anyMatch = users.stream().anyMatch(user -> "domain".equals(user.getName()));
Copy the code
  • All matching

Whether all the names in the collection are called domains

boolean allMatch = users.stream().allMatch(user -> "domain".equals(user.getName()));
Copy the code
  • Don’t match

Whether the collection does not have a domain name

boolean noneMatch = users.stream().noneMatch(user -> "domain".equals(user.getName()));
Copy the code

Optional

Optional is an API provided by Java8 to address null security issues. Consider the following example

  • I want to get a value from the User object like this:
user = userService.getUser();
if (user == null) {
 throw new Excepiton("User does not exist");
}

Copy the code

As you can see, the code becomes very verbose for nulling the data. Optional provides an API to make this short check more elegant.

  • orElseThrow
User user = Optional.ofNullable(userService.getUser()).orElseThrow(() -> new Exception("User is empty, user is empty"));

Copy the code

The above call to orElseThrow throws the corresponding exception if user is null. Optional.ofNullable specifies the object to operate on.

  • orElseGet
        String name = Optional.ofNullable(user.getPerson().getName()).orElseGet(() -> "domain");

Copy the code

The default value returned when the object is null using orElseGet.