1.lambda表达式初体验
lambda表达式是一个匿名函数,我们可以将lambda表达式理解为一段可以传递的代码(将代码像数据一样传递)
可以写出更为简洁的代码
场景描述:
创建一个对象集合,删选出符合要求的对象(1.删选出工资大于8000的 2.删除出年龄大于18的)
对象集合如下:
List<Employee> employees = Arrays.asList(
new Employee("吴孟达", 18, 18000.0),
new Employee("刘丹", 19, 10000.0),
new Employee("赵四", 20, 5000.0),
new Employee("王五", 25, 7000.0),
new Employee("李六", 30, 8000.0)
);
1.第一种方式(如果按照正常处理方法,会给每个筛选都创建一个方法,但是如果删选条件发生变化,就得创建一个新的方法,会造成方法的冗余 )
示例代码如下:
/**
* 定义一个根据工资筛选员工的方法
* @param employees:员工列表
* @return 删选后的员工
*/
public List<Employee> employeesFilterBySalary(List<Employee> employees){
List<Employee> employeeList=new ArrayList<>();
for (Employee employee : employees) {
if (employee.getSalary()>8000)
employeeList.add(employee);
}
return employeeList;
}
/*
测试普通删选方式
*/
@Test
public void testEmployeeFilterBySalary(){
List<Employee> employeeList = employeesFilterBySalary(employees);
for (Employee employee : employeeList) {
System.out.println(employee);
}
}
如果更改了工资要大于6000时,得重新写个方法,这样虽然可以达到目的,但是造成了代码的冗余
2.第二种方式:采用一种设计模式,叫做策略模式,值得推荐
2.1 先定义一个接口
/*
定义一个借口并设置泛型以传入到方法中
定义的方法返回boolean值,该方法进行过滤,有不同的实现类实现该接口,从而达到不同的筛选效果
*/
public interface EmployeeFilter<T> {
public boolean employeeFilter(T t);
}
2.2 接口实现类1(根据工资进行删选:对于传入的员工对象,如果工资大于8000,返回true)
public class EmployeeFilterBySalary implements EmployeeFilter<Employee> {
@Override
public boolean employeeFilter(Employee employee) {
return employee.getSalary() > 8000 ? true : false;
}
}
2.3 接口实现类2(根据年龄进行筛选)
public class EmployeeFilterByAge implements EmployeeFilter<Employee> {
@Override
public boolean employeeFilter(Employee employee) {
return employee.getAge() > 18 ? true : false;
}
}
2.4 定义统一的筛选方法
/*
进行员工删选
*/
重点1:传入员工列表,删选策略的接口(重要)
public List<Employee> employeesFilter(List<Employee> list, EmployeeFilter<Employee> employeeFilter) {
List<Employee> employeeList = new ArrayList<>();
for (Employee employee : list) {
if (employeeFilter.employeeFilter(employee))
employeeList.add(employee);
}
return employeeList;
}
2.5 测试
/**
* 改造1:使用策略模式进行改造
*/
@Test
public void test01() {
System.out.println("删选出工资大于8000的");
1.重点1:传入不同的接口实现类,即传入不同的筛选策略,达到不同的筛选效果
List<Employee> employeeListFileterBySalary = employeesFilter(employees, new EmployeeFilterBySalary());
for (Employee employee : employeeListFileterBySalary) {
System.out.println(employee);
}
System.out.println("-------------------------");
2.重点2:传入不同的接口实现类,即传入不同的筛选策略,达到不同的筛选效果
System.out.println("删选出年龄大于18的");
List<Employee> employeeListFilterByAge = employeesFilter(employees, new EmployeeFilterByAge());
for (Employee employee : employeeListFilterByAge) {
System.out.println(employee);
}
}
改造2:使用匿名内部类的形式:不需要定义接口实现类,而是在创建接口实例时直接重写接口的方法
/*
进行员工删选
*/
public List<Employee> employeesFilter(List<Employee> list, EmployeeFilter<Employee> employeeFilter) {
List<Employee> employeeList = new ArrayList<>();
for (Employee employee : list) {
if (employeeFilter.employeeFilter(employee))
employeeList.add(employee);
}
return employeeList;
}
/*
使用匿名内部类
*/
@Test
public void test02() {
System.out.println("测试匿名内部类");
重点1:创建接口实例,直接实现接口中的方法
List<Employee> employeeList = employeesFilter(employees, new EmployeeFilter<Employee>() {
@Override
public boolean employeeFilter(Employee employee) {
return employee.getSalary() > 8000 ? true : false;
}
});
for (Employee employee : employeeList) {
System.out.println(employee);
}
}
3.改造3:使用lambda表达式:
/*
进行员工删选
*/
重点1:此处传参使用了泛型 ,这也是下面能使用(e) 的原因
public List<Employee> employeesFilter(List<Employee> list, EmployeeFilter<Employee> employeeFilter) {
List<Employee> employeeList = new ArrayList<>();
for (Employee employee : list) {
if (employeeFilter.employeeFilter(employee))
employeeList.add(employee);
}
return employeeList;
}
/*
优化3:使用lambda表达式
*/
@Test
public void testLambda() {
System.out.println("删选出年龄大于18的");
List<Employee> employeeListFilterByAge = employeesFilter(employees, (e) -> e.getAge() > 18);
employeeListFilterByAge.forEach(System.out::println);
System.out.println("-------------------------");
System.out.println("删选出工资大于8000的");
List<Employee> employeeListFilterBySalary = employeesFilter(employees, (e) -> e.getSalary() > 8000.0);
employeeListFilterBySalary.forEach(System.out::println);
}
4.使用Strem流:
/*
优化方法4:使用Stream流:发现其不需要实现接口,定义公共的筛选方法,直接像操作数据库一样直接进行筛选输出,nb
*/
@Test
public void testByStream() {
employees.stream()
.filter((e) -> e.getSalary() > 8000)
.forEach(System.out::println);
}