做网站费用会计分录,北京英众数字科技有限公司,宝盒官方网站,wordpress主题贝宝目录标题 为什么使用 Lambda 表达式示例一#xff1a;先看一个常用排序类Comparator的示例示例二#xff1a;筛选员工数据的示例传统方式实现的示例策略模式优化的示例 Lambda 基础语法语法格式一#xff1a;无参数#xff0c;无返回值语法格式二#xff1a;有一个参数先看一个常用排序类Comparator的示例示例二筛选员工数据的示例传统方式实现的示例策略模式优化的示例 Lambda 基础语法语法格式一无参数无返回值语法格式二有一个参数并且无返回值语法格式三若只有一个参数小括号可以省略不写语法格式四有两个以上的参数有返回值并且 Lambda 体中有多条语句语法格式五若 Lambda 体中只有一条语句 return 和 大括号都可以省略不写语法格式六Lambda 表达式的参数列表的数据类型可以省略不写 Lambda 表达式需要“函数式接口”的支持JDK8自带的函数式接口 为什么使用 Lambda 表达式
示例一先看一个常用排序类Comparator的示例
ComparatorString com new ComparatorString(){Overridepublic int compare(String o1, String o2) {return Integer.compare(o1.length(), o2.length());}
};
TreeSetString ts new TreeSet(com);代码再简化一点匿名内部类写法
TreeSetString ts new TreeSet(new ComparatorString(){Overridepublic int compare(String o1, String o2) {return Integer.compare(o1.length(), o2.length());}
});简化后还是有代码冗余实际有用的代码就“Integer.compare(o1.length(), o2.length())” 这一行。 这时Lambda 表达式闪亮登场
ComparatorString com (o1, o2) - Integer.compare(o1.length(), o2.length());
TreeSetString ts new TreeSet(com);代码是不是简洁很多了。
示例二筛选员工数据的示例
员工类
public class Employee {private int id;private String name;private int age;private double salary;// get()、set()、hashCode()、equals()、toString()省略
}现在有一批员工数据
ListEmployee emps Arrays.asList(new Employee(101, 张三, 18, 9999.99),new Employee(102, 李四, 59, 6666.66),new Employee(103, 王五, 28, 3333.33),new Employee(104, 赵六, 8, 7777.77),new Employee(105, 田七, 38, 5555.55)
);传统方式实现的示例
有以下业务需求通过传统方式实现如下
/*** 需求1获取公司中年龄小于 35 岁的员工信息* param emps* return*/
public ListEmployee filterEmployeeAge(ListEmployee emps){ListEmployee list new ArrayList();for (Employee emp : emps) {if(emp.getAge() 35){list.add(emp);}}return list;
}/*** 需求2获取公司中工资大于 5000 的员工信息* param emps* return*/
public ListEmployee filterEmployeeSalary(ListEmployee emps){ListEmployee list new ArrayList();for (Employee emp : emps) {if(emp.getSalary() 5000){list.add(emp);}}return list;
}仔细观察几个方法发现只有if()判断一行代码不一样其他代码都相同。
优化思路提取封装变化的部分相同代码复用另外还要考虑再有类似需求的扩展性比如按性别过滤、按姓氏过滤等。此时我们会想到一种设计模式策略模式。
策略模式优化的示例
定义顶层接口
FunctionalInterface
public interface MyPredicateT {boolean test(T t);
}根据业务需求定义接口的实现类也即上面变化的部分
/*** 按年龄过滤的类*/
public class FilterEmployeeForAge implements MyPredicateEmployee{Overridepublic boolean test(Employee t) {return t.getAge() 35;}
}/*** 按工资过滤的类*/
public class FilterEmployeeForSalary implements MyPredicateEmployee {Overridepublic boolean test(Employee t) {return t.getSalary() 5000;}
}相同的部分也即不变的部分
public ListEmployee filterEmployee(ListEmployee emps, MyPredicateEmployee predicate){ListEmployee list new ArrayList();for (Employee employee : emps) {if(predicate.test(employee)){ //这一行具体实现类实现list.add(employee);}}return list;
}策略模式实现上面业务需求
//需求1获取公司中年龄小于 35 的员工信息
ListEmployee list filterEmployee(emps, new FilterEmployeeForAge());
for (Employee employee : list) {System.out.println(employee);
}//需求2获取公司中工资大于 5000 的员工信息
ListEmployee list2 filterEmployee(emps, new FilterEmployeeForSalary());
for (Employee employee : list2) {System.out.println(employee);
}这样业务代码过滤员工数据时就简洁了很多也满足了代码的开闭原则。 如果以后有其他过滤员工信息的需求比如按性别过滤的需求我们再新建一个过滤实现类即可。 但如果过滤的业务需求很多那么要新建的过滤实现类也要很多。可以不新建那么多小类吗 可以方式一匿名内部类
ListEmployee list filterEmployee(emps, new MyPredicateEmployee() {Overridepublic boolean test(Employee t) {return t.getSalary() 5000;}
});
for (Employee employee : list) {System.out.println(employee);
}方式二Lambda表达式
ListEmployee list filterEmployee(emps, (e) - e.getSalary() 5000);
list.forEach(System.out::println);对比一下Lambda表达式的方式是不是代码更简洁清晰。 Lambda 基础语法
Java8中引入了一个新的操作符 “-” 该操作符称为箭头操作符或 Lambda 操作符。
箭头操作符将 Lambda 表达式拆分成两部分
左侧Lambda 表达式的参数列表右侧Lambda 表达式中所需执行的功能 即实现类的方法体
语法格式一无参数无返回值
() - System.out.println(“Hello Lambda!”);
int num 0;//jdk1.7及以前必须加final
Runnable r new Runnable() {Overridepublic void run() {System.out.println(Hello World! num);}
};
r.run();Runnable r1 () - System.out.println(Hello Lambda! num);
r1.run();语法格式二有一个参数并且无返回值
ConsumerString con (x) - System.out.println(x);
con.accept(Hello Lambda!);语法格式三若只有一个参数小括号可以省略不写
ConsumerString con x - System.out.println(x);
con.accept(Hello Lambda!);语法格式四有两个以上的参数有返回值并且 Lambda 体中有多条语句
有多条语句时方法体加**{}有返回值加return**。
ComparatorInteger com (x, y) - {System.out.println(函数式接口);return Integer.compare(x, y);
};语法格式五若 Lambda 体中只有一条语句 return 和 大括号都可以省略不写
ComparatorInteger com (x, y) - Integer.compare(x, y);语法格式六Lambda 表达式的参数列表的数据类型可以省略不写
因为JVM编译器通过上下文推断出数据类型即“类型推断”
ComparatorInteger com (Integer x, Integer y) - Integer.compare(x, y);
//根据前面ComparatorInteger里指定的Integer推断的
ComparatorInteger com (x, y) - Integer.compare(x, y);String[] arr {“aaa”, “bbb”, “ccc”}; //值简写也是根据前面String类型推断的 List String list new ArrayList(); //ArrayList里没写String也是根据List String里推断出来的 Lambda 表达式需要“函数式接口”的支持
函数式接口接口中只有一个抽象方法的接口称为函数式接口。 可以使用注 FunctionalInterface注解修饰该注解可以检查是否是函数式接口比如接口类里定义了2个接口方法就会提示错误。
JDK8自带的函数式接口
函数式接口参数类型返回类型用途Consumer TTvoid对类型为T的对象应用操作包含方法void accept(T t)Supplier T 供给型接口无T返回类型为T的对象包含方法T get();Function T, R 函数型接口TR对类型为T的对象应用操作并返回结果。结果是R类型的对象。包含方法R apply(T t);Predicate T 断定型接口Tboolean确定类型为T的对象是否满足某约束并返回boolean 值。包含方法boolean test(T t); 示例
Test
public void test7(){Integer num operation2(100, (x) - x * x);System.out.println(num);System.out.println(operation2(200, (y) - y 200));
}public Integer operation2(Integer num, FunctionInteger, Integer fun){return fun.apply(num);
}