为什么使用Lambda表达式?
- Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出简介,更灵活的代码。作为一种更紧凑的代码风格,使java的语言表达能力得到了提升。
接下来从代码上来看看Lambda 有什么好?
--下面先不是用lambda表达式
/**
* 员工实体类
*
* @author Administrator
* @version 1.0
* @date 2019/11/6 10:54
*/
public class Employee {
private Integer age;
private String name;
private Double salary;
有参/无参构造器
get/set方法
toString
}
初始化员工类如下
//初始化员工类集合
static List<Employee> employees = Arrays.asList(
new Employee("张三", 18, 3333.33),
new Employee("李四", 28, 5555.55),
new Employee("王五", 38, 6666.66),
new Employee("赵柳", 48, 7777.77),
new Employee("田七", 58, 8888.88)
);
需求1: 查出年龄大于38的员工集合
实现如下
//需求:查出年龄大于38的员工集合
public List<Employee> filterEmployee() {
List<Employee> employeeList = new ArrayList<>();
for (Employee each : employees) {
if (each.getAge() > 35) {
employeeList.add(each);
}
}
return employeeList;
}
@Test
public void testEmployee(){
System.out.println("-------需求1---------");
List<Employee> employeeList = filterEmployee();
for (Employee employee : employeeList) {
System.out.println(employee);
}
}
有添加一个需求2:获取当前公司员工工资大于4500 的员工信息
@Test
public void testEmployee() {
System.out.println("-------需求1---------");
List<Employee> employeeList = filterEmployee();
for (Employee employee : employeeList) {
System.out.println(employee);
}
System.out.println("--------需求2------------");
List<Employee> employees1 = filterEmployee1();
for (Employee employee : employees1) {
System.out.println(employee);
}
}
//需求2:获取当前公司员工工资大于4500 的员工信息
public List<Employee> filterEmployee1() {
List<Employee> employeeList = new ArrayList<>();
for (Employee each : employees) {
if (each.getSalary() > 4500) {
employeeList.add(each);
}
}
return employeeList;
}
运行结果如下
从需求1到需求2再到等等需求
- 改变的就是each.getAget() 和 each.getSalary()方法,剩下的代码都没有进行改变,比如说我们现在有一个需求查出员工年龄小于35岁的员工,这样我们就可以复制 filterEmployee()这个方法 ,唯一改变的就是把里面大于改为小于,这样代码就冗余了。
- 对代码最好的优化方式,不是把公共的代码提取出来,而是设计模式。
优化方式1
创建策略模式员工条件接口
public interface MyPredicate<T> {
public boolean test(T t);
}
创建实现类实现于 MyPredicate ,如根据年龄查询
public class FilterEmployeeByAge implements MyPredicate<Employee> {
@Override
public boolean test(Employee employee) {
return employee.getAge() > 35;
}
}
接下来就是方法实现如下-->查出年龄大于35的员工信息
//优化方式1
public List<Employee> filterEmployee2(MyPredicate<Employee> myPredicate) {
List<Employee> emps = new ArrayList<>();
for (Employee emp : employees) {
if (myPredicate.test(emp)) {
emps.add(emp);
}
}
return emps;
}
@Test
public void test02(){
List<Employee> employeeList = filterEmployee2(new FilterEmployeeByAge());
for (Employee employee : employeeList) {
System.out.println(employee);
}
}
如果要实现需求2,直接写一个根据工资查询的接口就可以了-->需求:查出工资大于4500的员工信息
public class FilterEmployeeBySalary implements MyPredicate<Employee> {
@Override
public boolean test(Employee e) {
return e.getSalary() > 4500;
}
}
在方法实现中直接可以共用方法 filterEmployee2(MyPredicate<Employee> myPredicate) 传入不同的策略模式,从而查询出不同的员工集合,如下
@Test
public void test02(){
System.out.println("-----优化后需求1-----");
List<Employee> employeeList = filterEmployee2(new FilterEmployeeByAge());
for (Employee employee : employeeList) {
System.out.println(employee);
}
System.out.println("-----优化后需求2-----");
List<Employee> employees = filterEmployee2(new FilterEmployeeBySalary());
for (Employee employee : employees) {
System.out.println(employee);
}
}
结果如下
- 比如说你以后添加不同的判断规则,直接通过写不同的实现类,然后传入判断规则,使用公共的查询方法,就可以查出员工集合
- 缺点,每次实现类的方法写了很少的内容,需要单独的创建一个类,这个类的创建是很多余的,优化方法2,参考下面
优化方法2-匿名内部类
//优化方法2 -匿名内部类
@Test
public void test03(){
System.out.println("--------优化2-查出大于35的员工信息----------------");
List<Employee> employees = filterEmployee2(new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getAge() > 35;
}
});
for (Employee employee : employees) {
System.out.println(employee);
}
System.out.println("--------优化2-查出员工工资大于4500的员工信息-----------");
List<Employee> employeeList = filterEmployee2(new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getSalary() > 4500;
}
});
for (Employee employee : employeeList) {
System.out.println(employee);
}
}
- 不知道你有没有发现,匿名内部类其实还是可以优化的,需求1与需求2 有用的代码只有一句
employee.getAge() > 35 和 employee.getSalary() > 4500 代码还是不够简洁,代码可读性比较差
运行结果如下
代码优化方法3-lambda表达式
//优化方法3-lambda
@Test
public void test04(){
System.out.println("-------优化3-查出大于35的员工信息--------");
List<Employee> employees = filterEmployee2(employee -> employee.getAge() > 35);
employees.forEach(System.out::println);
System.out.println("-------优化3-查出员工工资大于4500的员工信息--------");
List<Employee> employeeList = filterEmployee2(employee -> employee.getSalary() > 4500);
employeeList.forEach(System.out::println);
}
结果为
如果对上面的表达式还不满意还有优化方式4,如下
优化方式4-stream api
//优化4 --stream api
@Test
public void test05(){
System.out.println("-------优化4-查出大于35的员工信息--------");
employees.stream()
.filter(e->e.getAge()>35)
.forEach(System.out::println);
System.out.println("-------优化4-查出员工工资大于4500的员工信息--------");
employees.stream()
.filter(e->e.getSalary()>4500)
.forEach(System.out::println);
System.out.println("-------优化4-查出员工工资大于4500的员工信息只取出前俩个--------");
employees.stream()
.filter(e->e.getSalary()>4500)
.limit(2)
.forEach(System.out::println);
System.out.println("-------优化4-取出员工集合中所有员工的名字--------");
employees.stream()
.map(Employee::getName)
.forEach(System.out::println);
}
结果如下
所以说以后再开发中,尽量使用lambda表达式,来提高代码的可读性