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)
@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.
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