Java8 fully interprets a

Source: Internet
Author: User
Tags instance method stream api

Java8 Full Interpretation

Java8 Full Interpretation
Objective
Some new features of JAVA8
1. Why use JAVA8?
1.1 First thought of the logic should be as follows
1.2 Use policy mode to solve this problem
1.3 Using policy mode and internal classes to solve problems
1.4 Use Policy mode and lambda method to solve this problem
1.5 use stream stream to solve this problem
2.LAMBDA Basic Syntax
2.1 No parameter no return value
2.2 has one parameter, and no return value
2.3 If there is only one argument, the parentheses can be omitted without writing
2.4 has more than two parameters, has a return value, and there are multiple statement function bodies in the LAMBDA body need to use {}
2.5 If there is only one statement in the Lambda body, both return and curly braces can be omitted.
The data type of the parameter list of the 2.6 Lambda expression can be omitted, because the JVM compiler infers the data type, which is the "type inference", through the context.
3. Function-Type interface
3.1 Custom Function interface
3.2 Built-in four core functional interfaces
Consumer: Consumer interface (only parameters are passed, no parameters are returned)
Supplier: Supply-only interface (no parameter, but return result)
Function: Functional interface (passing in a type parameter, returning the result of a type)
Predicate: Assertion-type interface (passing in a type parameter, returning a boolean-type result)
Other important functions
4. Method references and constructor references
4.1 Method Reference
4.2 Constructor Reference
4.3 Array references

Objective

Java8 has been released for a long time, I am learning after java8 feel java8 really good, this article is based on Silicon Valley JAVA8 video finishing, the article slowly gradually easy to understand.

Some new features of JAVA8
    • Lambda expression
    • Function-Type interface
    • Method reference with constructor reference
    • Stream API
    • The default method and static method in the interface
    • New Time Date API
    • Other new features

The most important of these is the use of lambda and stream

1. Why use JAVA8?

Here is a small case to explain the convenience of using JAVA8

    • If there is such an interview problem, ask the company employees of the age of >35 years of information and salary >5000 employee information?

Employee Class (EMPLOYEE.CLSSS)

package java8.whytostudylamdba;public class Employee {    private String name;    private int age;    private double sal;    public Employee(String name, int age, double sal) {        this.name = name;        this.age = age;        this.sal = sal;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public double getSal() {        return sal;    }    public void setSal(double sal) {        this.sal = sal;    }    @Override    public String toString() {        return "Employee{" +                "name=‘" + name + ‘\‘‘ +                ", age=" + age +                ", sal=" + sal +                ‘}‘;    }}

The employee table given

List<Employee> employees= Arrays.asList(            new Employee("张三",18,3000.00),            new Employee("李思思",25,3500.00),            new Employee("王五",30,6000.00),            new Employee("赵六",36,4500.00),            new Employee("天琪",50,6000.00),            new Employee("王八",18,38000.00)            );

Okay, let's start with the logic.

1.1 First thought of the logic should be as follows
  public list<employee> filterempbyage (list<employee> employeelist) {list<employee> emp        s = new arraylist<> ();            for (Employee e:employeelist) {if (E.getage () > +) {emps.add (e);    }} return emps;  } public list<employee> Filterempbysal (list<employee> employeelist) {list<employee> emps = new        Arraylist<> ();            for (Employee e:employeelist) {if (E.getsal () >5000) {Emps.add (e);    }} return emps;        } @Test public void Test2 () {list<employee> employees = filterempbyage (this.employees);        for (Employee e:employees) {System.out.println (e);        } System.out.println ("---------");        list<employee> employees1 = filterempbysal (this.employees);        for (Employee e:employees1) {System.out.println (e); }    }

This solution is sure to be possible, but this method can be thought of, can you use this solution to hand over? Definitely not, the following optimization.

1.2 Use policy mode to solve this problem

We mainly judge the age and salary of the employees, so we need an incoming employee, return the Boolean type method, the policy interface Myfilter

public interface MyFilter<T> {    boolean filter(T t);}

Filter Age Class (Filterbyage.class)

public class FilterByAge implements MyFilter<Employee> {    @Override    public boolean filter(Employee employee) {        return employee.getAge()>35;    }}

Filter Salary Class (Filterbysal.class)

public class FilterBySal implements MyFilter<Employee> {    @Override    public boolean filter(Employee employee) {        return employee.getSal()>5000;    }}

Use policy mode to solve this problem

public List<Employee> filterEmp(List<Employee> employeeList, MyFilter<Employee> filter) {        List<Employee> emps = new ArrayList<>();        for (Employee e:employeeList) {            if (filter.filter(e)) {                emps.add(e);            }        }        return emps;    }    @Test    public void test3(){        List<Employee> emps = filterEmp(employees, new FilterByAge());        for (Employee e : emps) {            System.out.println(e);        }        System.out.println("-------------");        List<Employee> emps1 = filterEmp(employees, new FilterBySal());        for (Employee e : emps1) {            System.out.println(e);        }    }

This method and the previous method than the use of the strategy model, it is certainly better than the previous method, but each implementation of a condition to create a new class inheritance myfilter seems a bit not good, then think of the implementation of the inner class to solve this shortcoming.

1.3 Using policy mode and internal classes to solve problems

The above Myfilter interface code does not move, two implementation classes can be deleted, using the above public List<Employee> filterEmp(List<Employee> employeeList, MyFilter<Employee> filter) method, in the form of internal class implementation.

@Test    public void test4(){        List<Employee> emp1 = filterEmp(this.employees, new MyFilter<Employee>() {            @Override            public boolean filter(Employee employee) {                return employee.getAge() > 35;            }        });        for (Employee e : emp1) {            System.out.println(e);        }        System.out.println("------------");        List<Employee> emp2 = filterEmp(this.employees, new MyFilter<Employee>() {            @Override            public boolean filter(Employee employee) {                return employee.getSal() > 5000;            }        });        for (Employee e : emp2) {            System.out.println(e);        }    }

This is a little further than the above, and if there is no lambda this way is already good, let's start with today's play: using Lambda to re-optimize the code above

1.4 Use Policy mode and lambda method to solve this problem

Like the method in 1.3, you don't have to change anything, that is, you use the LABMDA expression when you call the Filteremp method

@Test    public void test5(){        List<Employee> em1 = filterEmp(this.employees, (e) -> e.getAge() > 35);        em1.forEach(System.out::println);        System.out.println("----------");        List<Employee> em2 = filterEmp(this.employees, (e) -> e.getSal()>5000);        em2.forEach(System.out::println);//1.8方法    }

You see, for inner classes, using lambda expressions is a very easy thing to do, and now you don't understand? Okay, I'll say it later. Corresponding optimizations do this to the point where it is no longer possible to optimize, and you can use this method to submit answers. Here's a more new way to solve this problem.

1.5 use stream stream to solve this problem

Stream Stream is 1.8 new, there is a static method of stream in the collection class, so all collections can use stream stream. The following method is used, the previous method is not, if you just saw this problem, only the employee class and the corresponding list collection data .

@Test    public void test6(){        employees.stream()                .filter((e)->e.getAge()>35)                .forEach(System.out::println);        System.out.println("----------");        employees.stream()                .filter((e) -> e.getSal() > 5000)                .forEach(System.out::println);    }

Can see very easy to solve the above problem, is not very strong, why learn java8, this is one of the reasons.

2.LAMBDA Basic Syntax

A new operator, "--" called the arrow operator or lambda operator, is introduced in Java8, which splits the LAMBDA expression into two parts:

    • Left: parameter list of LAMBDA expressions
    • Right: The function that you need to perform in a lambda expression, the lambda body
2.1 No parameter no return value
() -> System.out.println("Hello Lambda!");
2.2 has one parameter, and no return value
(x) -> System.out.println(x)
2.3 If there is only one argument, the parentheses can be omitted without writing
x -> System.out.println(x)
2.4 has more than two parameters, has a return value, and there are multiple statement function bodies in the LAMBDA body need to use {}
Comparator<Integer> com = (x, y) -> {         System.out.println("函数式接口");         return Integer.compare(x, y);        };
2.5 If there is only one statement in the Lambda body, both return and curly braces can be omitted.
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
The data type of the parameter list of the 2.6 Lambda expression can be omitted, because the JVM compiler infers the data type, which is the "type inference", through the context.
(Integer x, Integer y) -> Integer.compare(x, y);

The parameter types in a LAMBDA expression are inferred by the compiler. There is no need to specify a type in a LAMBDA expression, and the program can still compile because Javac infers the type of the parameter in the background based on the context of the program. The type of the LAMBDA expression depends on the context and is inferred by the compiler. This is called "type inference."

    • Allied: About a bracket
    • Xia Lian: Left inference type Province
    • GUANGPI: Can save the province
3. Function-Type interface
    • Functional interface: An interface in which there is only one abstract method, called a functional interface.
    • You can create an object for that interface through a lambda expression. (If a lambda expression throws a checked exception, the exception needs to be declared on the abstract method of the target interface).
    • We can use the @functionalinterface annotation on any functional interface to check if it is a functional interface, and Javadoc also contains a declaration that the interface is a functional interface.
3.1 Custom Function interface

If we want to turn a string of letters into uppercase, this time we analyze with a custom function interface: We need to pass in an element of type T (String), after a series of operations (such as uppercase letters), returns an element of type T (String)

    • function is (myfuntion)
@FunctionalInterfacepublic interface MyFunction<T>{    T apply(T t);}

You can see the use of @functionalinterface annotations on the interface, Note: do not use public to modify the method in the interface

    • Ways to convert letters to uppercase
public String toUpperString3(String str,MyFunction<String> func) {        return func.apply(str);    }

Here you see the Apply method of passing STR into myfunction.

    • Use
public void test() {        String upStr = toUpperString3("abc", (e) -> e.toUpperCase());        System.out.println(upStr);    }

The general custom function interface is used in this way, the most important thing is the custom function interface, the function interface to match the type we want to manipulate. For example, to avoid the new function interface for each use, a series of function interfaces are defined in JAVA8.

3.2 Built-in four core functional interfaces

The following four functional interfaces are commonly used by us, and some of the other interfaces are extended by inheriting these four kinds of functions, which must be remembered by the four kinds of interfaces.

Consumer
    • Method: void Accept (T t);
    • Function: Apply an action to an object of type T

Use

//1.消费型    public void happy(String name, Consumer<String> con) {        con.accept(name);    }    @Test    public void test1() {        happy("李四",(x)-> System.out.println(x+"大保健"));    }
Supplier
    • Method: T get ();
    • Function: Returns an object of type T
      Use
//2.供给型    public List<Integer> getNum(Integer size, Supplier<Integer> supplier) {        List<Integer> nums = new ArrayList<>();        for (int i=0;i<size;i++) {            Integer integer = supplier.get();            nums.add(integer);        }        return nums;    }    @Test    public void test2() {        List<Integer> nums = getNum(6, () -> (int) (Math.random() * 100));        for (Integer i : nums) {            System.out.println(i+"");        }    }
Function
    • Method: R apply (T T);
    • Action: Applies an operation to an object of type T and returns the result. The result is an object of type R.

Use

public String subStr(String str, Function<String, String> function) {        return function.apply(str);    }    @Test    public void test3() {        String str = subStr("hellokotlin", (x) -> x.substring(5));        System.out.println(str);    }
predicate
    • Method: Boolean Test (T T);
    • Effect: Determines whether an object of type T satisfies a constraint and returns a Boolean value.

Use

public boolean isContinKotlin(String str, Predicate<String> pre) {        return pre.test(str);    }    @Testpublic void test5() {        System.out.println(isContinKotlin("stKotlin",(str)->str.contains("Kotlin")));    }
Other important functions
function Interface parameter Type return type Use
Bifunction < t,u,r> T,u R Applies an action to the type T,u parameter, returning the result of type R. The containing method is rapply (TT,UU);
unaryoperator< t> (function sub-interface) T T A unary operation is performed on an object of type T and returns the result of type T. Contains the method for Tapply (Tt);
binaryoperator< t> (bifunction sub-Interface) T,t T A two-dollar operation is performed on an object of type T and returns the result of type T. The containing method is tapply (TT1,TT2);
biconsumer< t,u> T,u T Applies an action to the type T,u parameter. Contains a method of Voidaccept (Tt,uu)
4. Method reference and Constructor reference 4.1 method reference

When you want to pass the action to the lambda body, there is already a way to implement it, you can use the method reference! (Implementing an abstract method's argument list must be consistent with the parameter list of the method reference Method!) Method Reference: Use the operator "::" to separate the name of the method from the names of the object or class.

The following three main use cases:

    • Object :: instance method
    • Class :: static method
    • Class :: instance method

1. Object ::* * Instance Method * *

Consumer<String> con = (str) -> ps.println(str);//等同于:Consumer<String> con3 = System.out::println;

System.out is an object

2. Class ::* * static Method * *

BiFunction<Double, Double, Double> fun = (x, y) -> Math.max(x, y);//等同于BiFunction<Double, Double, Double> fun2 = Math::max;

3. Class ::* * Instance Method * *

BiPredicate<String, String> bp = (x, y) -> x.equals(y);//等同于BiPredicate<String, String> bp2 = String::equals;

Attention:
The ① method references the parameter list of the referenced method and the return value type, which needs to be consistent with the parameter list and return value type of the abstract method in the function interface!
② if the first parameter of the lambda parameter list is the caller of the instance method, the second argument (or no argument) is the argument of the instance method (third), format: Classname::methodname

4.2 Constructor Reference

Combined with a functional interface, it is automatically compatible with the method in the functional interface. The constructor reference can be assigned to the defined method, and the constructor parameter list is consistent with the parameter list of the abstract method in the interface!

//无参构造函数Supplier<Employee> sup = () -> new Employee();//等同于,调用的是无参构造函数Function<String, Employee> fun = Employee::new;//有参构造函数Function<String,Employee> fun1=(e)->new Employee(e);//等同于,调用的是有参构造函数Function<String, Employee> fun = Employee::new;
4.3 Array references
//传入一个Integer返回一个Integer长度的数组Function<Integer, String[]> fun = (args) -> new String[args];//等同于Function<Integer,String[]> fun3=String[]::new;

Java8 fully interprets a

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.