Lambda表达式和方法引用
1 , 为什么用lambda表达式
将重复固定的代码写法简单化
2 ,lambda表达式的实质
对函数式接口的实现(一个接口中只有一个抽象方法的接口被称为函数式接口)
package com.moreas.lambda; public class Employee { private String name; private int age; private double salary; public Employee(String name, int age, double salary) { super(); this.name = name; this.age = age; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } }
函数式接口
package com.moreas.lambda; public interface MyPredicate<T> { public boolean test(T t); }
package com.moreas.lambda; import java.util.ArrayList; import java.util.List; public class Client { 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; } public static void main(String[] args) { //new Client().test(); new Client().test1(); } public void test() { List<Employee> employees = new ArrayList<>(); employees.add( new Employee("zhangsan1", 16, 1500)); employees.add( new Employee("zhangsan2", 16, 300)); employees.add( new Employee("zhangsan3", 16, 400)); employees.add( new Employee("zhangsan4", 16, 1200)); List<Employee> list = filterEmployee(employees, new MyPredicate<Employee>() { @Override public boolean test(Employee t) { // TODO Auto-generated method stub return t.getSalary() <= 500; } }); for (Employee employee : list) { System.out.println(employee.getName()); } } public void test1() { List<Employee> employees = new ArrayList<>(); employees.add( new Employee("zhangsan1", 16, 1500)); employees.add( new Employee("zhangsan2", 16, 300)); employees.add( new Employee("zhangsan3", 16, 400)); employees.add( new Employee("zhangsan4", 16, 1200)); List<Employee> list = filterEmployee(employees, (e) -> e.getSalary() <= 500); list.forEach(x -> System.out.println(x.getName())); } }
lambda 表达式子的几种形式
一 无参数 ,无返回值
Runnable r1 = () -> System.out.println("Hello Lambda!"); r1.run();
二 有一个参数 ,无返回值
Consumer<String> con = ( x ) -> System.out.println(x); con.accept("hello world!");
三 有多个参数 ,有返回值
Comparator<Integer> com = (x, y) -> { System.out.println("函数式接口"); return Integer.compare(x, y); };
四 有多个参数, lambda体中只有一句话,return 和大括号可以省略
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
四个核心的函数式接口
//Consumer<T> 消费型接口 : @Test public void test1(){ happy(1000, (m) -> System.out.println("吃个饭,消费了:" + m + "元")); } public void happy(double money, Consumer<Double> con){ con.accept(money); }
//Supplier<T> 供给型接口 : @Test public void test2(){ List<Integer> numList = getNumList(10, () -> (int)(Math.random() * 100)); for (Integer num : numList) { System.out.println(num); } } //需求:产生指定个数的整数,并放入集合中 public List<Integer> getNumList(int num, Supplier<Integer> sup){ List<Integer> list = new ArrayList<>(); for (int i = 0; i < num; i++) { Integer n = sup.get(); list.add(n); } return list; }
@Test public void test3(){ String newStr = strHandler("\t\t\t hello world ", (str) -> str.trim()); System.out.println(newStr); String subStr = strHandler("hello world", (str) -> str.substring(2, 5)); System.out.println(subStr); } //需求:用于处理字符串 public String strHandler(String str, Function<String, String> fun){ return fun.apply(str); }
//Predicate<T> 断言型接口: @Test public void test4(){ List<String> list = Arrays.asList("Hello", "world", "Lambda", "ok"); List<String> strList = filterStr(list, (s) -> s.length() > 3); for (String str : strList) { System.out.println(str); } } //需求:将满足条件的字符串,放入集合中 public List<String> filterStr(List<String> list, Predicate<String> pre){ List<String> strList = new ArrayList<>(); for (String str : list) { if(pre.test(str)){ strList.add(str); } } return strList; }
方法引用
引用静态方法:Class::staticMethodName
引用某个对象的实例方法:object::instanceMethodName
引用某个类型的任意对象的实例方法:Class::instancemethodName
引用构造方法:ClassName::new
//对象 :: 实例方法名 @Test public void test1(){ // 实例方法的参数和返回值类型与函数式接口中抽象方法的参数和返回值类型相同 Consumer<String> con3 = System.out::println; con3.accept("Hello Java8!"); }
//类名 :: 静态方法名 @Test public void test4(){ Comparator<Integer> com2 = Integer::compare; }
//类名 :: 实例方法名 @Test public void test9(){ //可以这样写的前提是,第一个参数是方法的调用者,第二个参数是方法的传参 BiPredicate<String, String> bp = String::equals; }
//构造器引用 @Test public void test7(){ //匹配无参构造器 Supplier<Employee> sup2 = Employee::new; Employee em = sup2.get(); //匹配一个参数的构造器 Function<String, Employee> fun = Employee::new; Employee em2 = fun.apply("zhangsan"); }
//数组引用 @Test public void test8(){ Function<Integer, String[]> fun = (x) -> new String[x]; String[] strs = fun.apply(10); System.out.println("--------------------------"); Function<Integer, String[]> fun2 = String[]::new; String[] strs2 = fun2.apply(10); System.out.println("--------------------------"); Function<Integer, Employee[]> fun3 = Employee[] :: new; Employee[] emps = fun3.apply(20); }
public class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public static int compareByAge(Person a, Person b) { return a.age.compareTo(b.age); } public static void main(String[] args) { //没有使用Lambda表达式 //test1(); //使用Lambda表达式 // test2(); //使用静态方法引用 test3(); //实例方法引用 test4(); } public static void test1() { Person[] persons = new Person[]{new Person("ZhangSan", 27), new Person("LiSi", 20), new Person("WangWu", 25)}; class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getAge().compareTo(b.getAge()); } } Arrays.sort(persons, new PersonAgeComparator()); Arrays.stream(persons).forEach(x -> System.out.println(x.getName())); } public static void test2() { Person[] persons = new Person[]{new Person("ZhangSan", 27), new Person("LiSi", 20), new Person("WangWu", 25)}; class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getAge().compareTo(b.getAge()); } } //第二个参数就是Comparator是一个函数式接口,可以传入一个Lambda表达式 Arrays.sort(persons, (a,b)->{ if(a.getAge() < b.getAge()){ return -1; } if(a.getAge() == b.getAge()){ return 0; } return 1; }); Arrays.stream(persons).forEach(x -> System.out.println(x.getName())); } public static void test3() { Person[] persons = new Person[]{new Person("ZhangSan", 27), new Person("LiSi", 20), new Person("WangWu", 25)}; class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getAge().compareTo(b.getAge()); } } //能够这样写的原因是Person的静态方法compareByAge的参数和返回值类型和Lambda保持一致 Arrays.sort(persons, Person::compareByAge); Arrays.stream(persons).forEach(x -> System.out.println(x.getName())); } public static void test4(){ Person person = new Person("ZhangSan", 18); //Lambda表达式 Supplier<String> supplier = ()-> { return person.getName();}; System.out.println(supplier.get()); //实例方法引用 supplier = person::getName; System.out.println(supplier.get()); } }