Before the server because the company has been using jdk1.7 environment java8 so many new features are not used in the project, so he took a few months before the company java environment upgrade process, and then start using the new syntax java8 properties in the project. Prior to his open source project has been using jdk1.8 so the new features can not be used in the company's project annoying, causing most of the junk code appears, taking advantage of the opportunity to Lambda expressions are summarized.
Why Lambada expression
Lambda expressions that white is an anonymous function, can be more straightforward expression of what you want to do
For a simple example, from the most primitive to traverse to achieve end-use Lambda expressions, you can easily find beautiful and simple Lambda expressions.
There is now a collection of student data, and these data need to be processed, and then filter out the required data
Demand :
1, check out the age of about 30 students
2, check out the tuition of greater than 18000.99
package com.weather.spring.cloud.initializrstart.dao;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* @program: msa-weather-master
* @description:
* @author: W.HL
* @create: 2019-04-24 20:33
**/
public @Data class Student
{
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private int age;
/**
* 学费
*/
private BigDecimal studyFee;
}
Initializing a data set
@Slf4j
public class LambdaTest
{
private static final int ageLit = 30;
private static final BigDecimal feeLit = new BigDecimal("18000.99");
List<Student> list = Arrays.asList(
new Student("赵敏",18,new BigDecimal("15000.11"))
,new Student("张无忌",20,new BigDecimal("16000.99"))
,new Student("周芷若",25,new BigDecimal("18000.99"))
,new Student("小昭",40,new BigDecimal("21000.99"))
,new Student("宋青书",50,new BigDecimal("31000.99"))
);
}
First, for loop filtering using the original query
/**
* 根据年龄过滤
* @param list
* @return
*/
public List<Student> filterStudentByAge(List<Student> list){
List<Student> resultList = new ArrayList<>();
for (Student student : list){
if(student.getAge()>ageLit){
resultList.add(student);
}
}
return resultList;
}
/**
* 根据学费过滤
* @param list
* @return
*/
public List<Student> filterStudentByFee(List<Student> list){
List<Student> resultList = new ArrayList<>();
for (Student student : list){
if(student.getStudyFee().compareTo(feeLit)>0){
resultList.add(student);
}
}
return resultList;
}
@Test
public void test(){
/*获取年龄大于30的学生*/
List<Student> list_1 = filterStudentByAge(list);
log.info("当前年龄大于30的学生有:{}",list_1.toString());
log.info("----------------------------------");
/*获取学费大于18000的学生*/
List<Student> list_2 = filterStudentByFee(list);
log.info("当前学费大大于18000.99元的学生有:{}",list_2.toString());
}
Found a lot of redundant code, then optimized using a strategy by mode to optimize
Second, the optimization program: use policy by mode to optimize
package com.weather.spring.cloud.initializrstart.service;
/**
* @program: msa-weather-master
* @description: This is a filer for student and return list
* @author: W.HL
* @create: 2019-04-24 20:59
**/
@FunctionalInterface
public interface FilterStudent<T>
{
boolean filterByCond(T t);
default void filterByCond3(T t){
System.out.println(t);
};
}
package com.weather.spring.cloud.initializrstart.service;
import com.weather.spring.cloud.initializrstart.dao.Student;
/**
* @program: msa-weather-master
* @description: This is filter student by age
* @author: W.HL
* @create: 2019-04-24 21:02
**/
public class FilterAgeStudentImpl implements FilterStudent<Student>
{
private static final int ageLit = 40;
@Override
public boolean filterByCond(Student student)
{
return student.getAge()>ageLit?true:false;
}
}
package com.weather.spring.cloud.initializrstart.service;
import com.weather.spring.cloud.initializrstart.dao.Student;
import java.math.BigDecimal;
/**
* @program: msa-weather-master
* @description: This is filter student by fee
* @author: W.HL
* @create: 2019-04-24 21:02
**/
public class FilterFeeStudentImpl implements FilterStudent<Student>
{
private static final BigDecimal feeLit = new BigDecimal("18000.99");
@Override
public boolean filterByCond(Student student)
{
return student.getStudyFee().compareTo(feeLit)>1?true:false;
}
}
Using a filtering interfaces and create separate filter implementation classes by age and filtered The implementation classes fees, to prepare the corresponding test methods; by passing a different implementation class is then implemented to filter by different conditions, it can be extended by filtration without modifying the original code based on the .
/**
* 优化一 使用策略者模式
*/
@Test
public void test1(){
/*获取年龄大于30的学生*/
List<Student> list_3 = filterByCond(list,new FilterAgeStudentImpl());
log.info("当前年龄大于30的学生有:{}",list_3.toString());
log.info("----------------------------------");
/*获取学费大于18000的学生*/
List<Student> list_4 = filterByCond(list,new FilterFeeStudentImpl());
log.info("当前学费大大于18000.99元的学生有:{}",list_4.toString());
}
public List<Student> filterByCond(List<Student> list,FilterStudent<Student> filterStudent){
List<Student> list_1 = new ArrayList<>();
for (Student student: list){
if(filterStudent.filterByCond(student)){
list_1.add(student);
}
}
return list_1;
}
Third, optimization Two: Use Lambda Expressions processing
/**
* 优化二 使用Lambda 表达式进行处理
*/
@Test
public void test2(){
/*获取年龄大于30的学生*/
List<Student> list_3 = filterByCond(list,(s) -> s.getAge()<=ageLit);
log.info("当前年龄大于30的学生有:{}",list_3.toString());
log.info("----------------------------------");
/*获取学费大于18000的学生*/
List<Student> list_4 = filterByCond(list,(s) -> s.getStudyFee().compareTo(feeLit)>0);
log.info("当前学费大于18000.99元的学生有:{}",list_4.toString());
}
May perhaps not quite understand what it means, you can use the Debug endpoint for detail, you can see the contents of Lambda expressions do perform the function of an anonymous function is actually performed braces from the chart below, which do not use concrete implementation class achieved by direct filtration in the case where filtering conditions.
Fourth, the optimization program 3: Use stream processing Lambda expressions and sorting process
/**
* 优化三 使用Lambda stream表达式进行处理
*/
@Test
public void test3(){
/*获取年龄大于30的学生 并按照年龄倒叙*/
List<Student> list_3 = list.stream()
.filter((e)>e.getAge()>ageLit)
.sorted(Comparator.comparing(Student::getAge).reversed())
.collect(Collectors.toList());
log.info("当前年龄大于30的学生有:{}",list_3.toString());
log.info("----------------------------------");
/*获取学费大于18000的学生*/
List<Student> list_4 = list.stream()
.filter((e)->e.getStudyFee().compareTo(feeLit)>0)
.collect(Collectors.toList());
log.info("当前学费大于18000.99元的学生有:{}",list_4.toString());
}
Demand change: just check out the tuition of students younger than 30 and not other data (filtering out the data stream returned by the result of the composition of a given application by Map)
/**
* 只获取年龄小于30的学生的学费
*/
@Test
public void test4(){
/*获取年龄大于30的学生*/
list.stream().filter(e->e.getAge()<30).map(e->e.getStudyFee()).forEach(e-> System.out.println(e));
log.info("----------------------------------");
}
Lambda expressions in terms of data filtering can clearly see from the above code that needs to come out of the original 10 lines are now nearly as long as the complete line of both, reduced a lot of junk codes
Lambda syntax summary:
jdk1.8 use "->" operator is also called Lambda arrow operator or operator, using the operator of the expression is divided into two parts:
On the left: Lambda Expressions argument list
Right: Function executed Lambda expressions (also known as function interface specific method)
Summary of the interface method parameter
Parameters and return value or
Parameters none Return value None | |
A parameter has no return value ( on the left in parentheses may be omitted ) | |
A plurality of parameters have a return value ( the Lambda body is only one statement, return and braces can be omitted ) | ![]() |
If the context specified in the argument types Lambda parameter list can omit the parameter type, JVM will automatically based on the context identification parameter type | |
Functional: Interface @FunctionalInterface add annotations can only contain an abstract method but may contain more than the default method for modifying the same time, the default method for modifying the implementation class can choose not to implement but can still be called directly use
@FunctionalInterface
public interface FilterStudent<T>
{
boolean filterByCond(T t);
// 如果在创建一个抽象接口 例如:boolean filterByCond5(T t);则会报错
default void filterByCond3(T t){
System.out.println(t);
};
}
For example, there are many of our most popular Comparator <T>, Runable, Consumer <T> and so on before java8