Java8 Lambda 表达式总结
- 最简单的Lambda 表达式
x-> System.out.println(x);
左边 为参数列表 参数类型写不写都行 Java JVM 会根据上下文 推断类型
右边 结构体 为函数功能的实现。
2.语法格式一 : 无参数,无返回值 ()->System.out.println("Hello Lambda!");
// Runnable 接口函数
public abstract void run();
@Test
public void test1(){
int num = 0; // jdk 1.7前 必须final 1.8 后系统默认加上
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello World !" + num);
}
};
r.run();
System.out.println("================");
Runnable r1 = () -> System.out.println("Hello Lambda");
r1.run();
}
上图可以看出 Lambda 使 代码更加简洁。
语法格式二: 一个参数,无返回值, 只有一个参数 小括号 可以不写
Consumer接口为Java8 的内置接口
Consumer<String> con = (x) -> System.out.println("x");
con.accept("Hello World");
Consumer<String> con2 = x -> System.out.println("x");
con2.accept("Hello World");
语法格式三:多个参数,有返回值 并且Lambda 体中有多条语句
@Test
public void test3(){
Comparator<Integer> com = (o1, o2) -> {
System.out.println("函数式接口");
return o1.compareTo(o2);
};
}
语法格式四: 若 Lambda 体只有一条语句 return 和 大括号都可以不写
@Test
public void test4(){
Integer num2 = operation(100,num -> num * num);
Integer num3 = operation(100,num -> {return num * num;});
System.out.println(num2);
System.out.println(num3);
}
二.Lambda 表达式 需要“函数式接口” 的支持
-
函数式接口: 接口中只有一个抽象方法的接口 , 称为 函数式接口
-
可以使用注解@FunctionalInterface 修饰 检查接口是否是函数式接口
- 练习
答案:
1.题目一
Employee 类
public int id;
public String name;
public int age;
public double salary;
public Employee(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
// get set toString ...... 自己补充
List<Employee> employees = 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)
);
@Test
public void test1(){
Collections.sort(employees,(e1,e2) -> {
if(e1.getAge() == e2.getAge()){
return e1.getName().compareTo(e2.getName());`在这里插入代码片`
}else {
return e1.getAge() - e2.getAge();
}
});
for (Employee e: employees) {
System.out.println(e);
}
}
2.题目二
@FunctionalInterface
public interface MyFunction {
String getValue (String str);
}
@Test
public void test2(){
System.out.println(strHandler("\t\t\t Hello World ", str -> str.replaceAll(" ", "")));
System.out.println(strHandler(" \t\t\t Hello World ", str -> str.trim()));
System.out.println(strHandler(" add \t\t\t Hello World ", str -> str.toUpperCase()));
System.out.println(strHandler(" add \t\t\t Hello World ", str -> str.substring(0,4)));
}
public String strHandler(String str,MyFunction mf){
return mf.getValue(str);
}
3.题目三
@FunctionalInterface
public interface MyFunction2<T,R> {
R getValue(T t1,T t2);
}
// 需求 : 对两个 long 型数据进行处理
public void op (Long l1,Long l2,MyFunction2<Long,Long> m){
System.out.println(m.getValue(l1,l2));
}
@Test
public void test3(){
op(100l,200l,(x,y) -> x+y);
op(100l,200l,(x,y) -> x-y);
op(100l,200l,(x,y) -> x*y);
}
三.Java 四大内置Lambda函数
1.Consumer<T> :消费型接口
void accept(T t);
2.Supplier<T> :供给型接口
T get();
3.Function<T,R> :函数型接口
R apply(T t);
4. Predicate<T> : 断言型接口
boolean test(T t);
package java8.lambda;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* @program: java8
* @description:
* @author: ChenYu
* @create: 2018-10-13 20:24
**/
public class TestLambda04 {
/*
1.Consumer<T> :消费型接口
void accept(T t);
* */
@Test
public void test(){
happy(10000,(x) -> System.out.println("消费 " + x + "元"));
}
public void happy(double money, Consumer<Double> con){
con.accept(money);
}
/*
2.Supplier<T> :供给型接口
T get();
*/
/* 产生指定个数的整数 并放入 集合中*/
@Test
public void test2(){
List<Integer> list = getNumList(10,() -> (int) (Math.random() * 100));
list.stream().forEach(System.out::println);
}
public List<Integer> getNumList(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add(sup.get());
}
return list;
}
/*
3.Function<T,R> :函数型接口
R apply(T t);
*/
/*
用于处理字符串
* */
@Test
public void test3(){
System.out.println(strHandler("\t\t\t Hello World ", str -> str.replaceAll(" ", "")));
System.out.println(strHandler(" \t\t\t Hello World ", str -> str.trim()));
System.out.println(strHandler(" add \t\t\t Hello World ", str -> str.toUpperCase()));
System.out.println(strHandler(" add \t\t\t Hello World ", str -> str.substring(0,4)));
}
public String strHandler(String str, Function<String,String> function){
return function.apply(str);
}
/*
4. Predicate<T> : 断言型接口
boolean test(T t);
*/
/*
把满足条件的字符串放入集合中
* */
@Test
public void test4(){
List<String> list = Arrays.asList("hello","test","aaa","www","ok");
List<String> resList = filterStr(list,s -> s.length()>=3);
resList.stream().forEach(System.out::println);
}
public List<String> filterStr(List<String> list, Predicate<String> predicate){
List<String> reslist = new ArrayList<>();
for (String s : list) {
if(predicate.test(s)){
reslist.add(s);
}
}
return reslist;
}
}
Lambda的优点演示
1.新建一个Employee 类
public int id;
public String name;
public int age;
public double salary;
public Employee(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
// 省略 get set toString等
2.首先有一个需求 是能根据员工的年龄或者工资进行过滤。
最原始的写法如下 这样代码冗长,可读性不好。
List<Employee> employees = 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)
);
public List<Employee> filterByAge(List<Employee> list){
List<Employee> emps = new ArrayList<>();
for (Employee employee: list) {
if(employee.age >= 35){
emps.add(employee);
}
}
return emps;
}
public List<Employee> filterBySalary(List<Employee> list){
List<Employee> emps = new ArrayList<>();
for (Employee employee: list) {
if(employee.salary >= 5000){
emps.add(employee);
}
}
return emps;
}
@Test
public void mytest(){
List<Employee> emps = filterByAge(employees);
for (Employee e: emps) {
System.out.println(e);
}
System.out.println("-------------------");
emps = filterBySalary(employees);
for (Employee e: emps) {
System.out.println(e);
}
}
3.用策略模式进行优化的写法
新建MyPredicate 类
@FunctionalInterface
public interface MyPredicate<T> {
boolean test(T t);
}
分别写两个实现类实现该接口
public class FilterEmployeeByAge implements MyPredicate<Employee>{
@Override
public boolean test(Employee employee) {
return employee.age >= 30;
}
}
public class FilterEmployeeBySalary implements MyPredicate<Employee>{
@Override
public boolean test(Employee employee) {
return employee.salary>=5000;
}
}
测试
// 优化方式 1 策略设计模式
// 缺点 类太多
// 提取共同代码
public List<Employee> filterEmployee(List<Employee> list,MyPredicate<Employee> mp){
List<Employee> emps = new ArrayList<>();
for (Employee employee: list) {
if(mp.test(employee)){
emps.add(employee);
}
}
return emps;
}
@Test
public void test4(){
List<Employee> emps = filterEmployee(employees,new FilterEmployeeByAge());
for (Employee e: emps) {
System.out.println(e);
}
System.out.println("-----------------------");
emps = filterEmployee(employees,new FilterEmployeeBySalary());
for (Employee e: emps) {
System.out.println(e);
}
}
在此基础上可以使用匿名内部类
// 优化方式二 匿名内部类
@Test
public void test5(){
List<Employee> emps = filterEmployee(employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.age>=30;
}
});
for (Employee e: emps) {
System.out.println(e);
}
System.out.println("-----------------------");
emps = filterEmployee(employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.salary>=3000;
}
});
for (Employee e: emps) {
System.out.println(e);
}
}
Lambda表达式写法
// 优化方式三 lanbda 表达式
@Test
public void test6(){
List<Employee> emps = filterEmployee(employees,(e) -> e.getAge()>=30);
emps.forEach(System.out::println);
System.out.println("-----------------------");
emps = filterEmployee(employees,employee -> employee.getSalary()>=5000);
emps.forEach(System.out::println);
}
// 优化方式四 lanbda 表达式 +streamAPI
@Test
public void test7(){
employees.stream().filter((employee -> employee.getAge()>=30)).forEach(System.out::println);
System.out.println("===================");
employees.stream().filter((employee -> employee.getSalary()>=5000)).forEach(System.out::println);
System.out.println("==================");
employees.stream().filter((employee -> employee.getSalary()>=5000)).limit(2).forEach(System.out::println);
}
项目地址:https://github.com/xiaoshabi2/java8