# java新特性-lambda表达式&方法引用&streamApi
Lambda表达式
本质:作为函数式接口的对象实例【不是函数,而是对象】
格式: -> :lambda操作符 或 箭头操作符 ->左边:lambda形参列表 (其实就是接口中的抽象方法的形参列表) ->右边:lambda体 (其实就是重写的抽象方法的方法体) 总结: ->左边:lambda形参列表的参数类型可以省略(类型推断);如果lambda形参列表只有一个参数,其一对()也可以省略 ->右边:lambda体应该使用一对{}包裹;如果lambda体只有一条执行语句(可能是return语句),省略这一对{}和return关键字
函数式接口
java.util.function包下定义了丰富的函数式接口 定义: 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口。我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。
java内置四大核心函数式接口:
// 消费型接口,参数类型T,返回类型void @FunctionalInterface public interface Consumer<T> { void accept(T t); } // 供给型接口,无参数,返回类型T @FunctionalInterface public interface Supplier<T> { T get(); } // 函数型接口,参数类型T,返回类型R @FunctionalInterface public interface Function<T, R> { R apply(T t); } // 断定型接口,参数类型T,返回类型Boolean @FunctionalInterface public interface Predicate<T> { boolean test(T t); }
方法引用
本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例。
所以方法引用,也是函数式接口的实例。
具体分为如下的三种情况: 情况1 对象 :: 非静态方法 情况2 类 :: 静态方法 情况3 类 :: 非静态方法 方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!(针对于情况1和情况2)
1 // 使用lombok 2 @data 3 public class Employee { 4 5 private int id; 6 private String name; 7 private int age; 8 private double salary 9 10 }View Code
方法引用代码示例:
1 public class MethodRefTest { 2 3 /** 4 * 情况一:对象 :: 实例方法 5 */ 6 //Consumer中的void accept(T t) 7 //PrintStream中的void println(T t) 8 @Test 9 public void test1() { 10 Consumer<String> con1 = str -> System.out.println(str); 11 con1.accept("北京"); 12 13 PrintStream ps = System.out; 14 Consumer<String> con2 = ps::println; 15 con2.accept("beijing"); 16 } 17 18 //Supplier中的T get() 19 //Employee中的String getName() 20 @Test 21 public void test2() { 22 Employee emp = new Employee(1001,"Tom",23,5600); 23 // 匿名内部类 24 Supplier<String> sup1 = new Supplier<String>() { 25 @Override 26 public String get() { 27 return emp.getName(); 28 } 29 }; 30 // lambda 31 Supplier<String> sup2 = () -> emp.getName(); 32 // 方法引用 33 Supplier<String> sup3 = emp::getName; 34 35 System.out.println(sup1.get()); 36 System.out.println(sup2.get()); 37 System.out.println(sup3.get()); 38 } 39 40 /** 41 * 情况二:类 :: 静态方法 42 */ 43 //Comparator中的int compare(T t1,T t2) 44 //Integer中的int compare(T t1,T t2) 45 @Test 46 public void test3() { 47 // 匿名内部类 48 Comparator<Integer> com1 = new Comparator<Integer>() { 49 @Override 50 public int compare(Integer o1, Integer o2) { 51 return Integer.compare(o1,o2); 52 } 53 }; 54 // lambda 55 Comparator<Integer> com2 = (t1,t2) -> Integer.compare(t1,t2); 56 // 方法引用 57 Comparator<Integer> com3 = Integer::compare; 58 59 System.out.println(com1.compare(12,21)); 60 System.out.println(com2.compare(12,3)); 61 System.out.println(com3.compare(12,12)); 62 63 } 64 65 //Function中的R apply(T t) 66 //Math中的Long round(Double d) 67 @Test 68 public void test4() { 69 // 匿名内部类 70 Function<Double,Long> func1 = new Function<Double, Long>() { 71 @Override 72 public Long apply(Double d) { 73 return Math.round(d); 74 } 75 }; 76 // lambda 77 Function<Double,Long> func2 = d -> Math.round(d); 78 // 方法引用 79 Function<Double,Long> func3 = Math::round; 80 81 System.out.println(func1.apply(12.6)); 82 System.out.println(func2.apply(12.6)); 83 System.out.println(func3.apply(12.6)); 84 } 85 86 /** 87 * 情况三:类 :: 实例方法 (有难度) 88 * 如下:参数1作为调用者,参数2作为方法参数 89 */ 90 91 // Comparator中的int comapre(T t1,T t2) 92 // String中的int t1.compareTo(t2) 93 @Test 94 public void test5() { 95 // 匿名内部类 96 Comparator<String> com1 = new Comparator<String>() { 97 @Override 98 public int compare(String o1, String o2) { 99 return o1.compareTo(o2); 100 } 101 }; 102 // lambda 103 Comparator<String> com2 = (s1,s2) -> s1.compareTo(s2); 104 // 方法引用 105 Comparator<String> com3 = String :: compareTo; 106 107 System.out.println(com1.compare("abd","abm")); 108 System.out.println(com2.compare("abd","abm")); 109 System.out.println(com3.compare("abd","abm")); 110 } 111 112 //BiPredicate中的boolean test(T t1, T t2); 113 //String中的boolean t1.equals(t2) 114 @Test 115 public void test6() { 116 // 匿名内部类 117 BiPredicate<String,String> pre1 = new BiPredicate<String, String>() { 118 @Override 119 public boolean test(String s1, String s2) { 120 return s1.equals(s2); 121 } 122 }; 123 // lambda 124 BiPredicate<String,String> pre2 = (s1,s2) -> s1.equals(s2); 125 // 方法引用 126 BiPredicate<String,String> pre3 = String :: equals; 127 128 System.out.println(pre1.test("abc","abd")); 129 System.out.println(pre2.test("abc","abd")); 130 System.out.println(pre3.test("abc","abd")); 131 } 132 133 // Function中的R apply(T t) 如下:t就是employee 134 // Employee中的String t.getName(); 135 @Test 136 public void test7() { 137 Employee employee = new Employee(1001, "Jerry", 23, 6000); 138 139 // 匿名内部类 140 Function<Employee,String> func1 = new Function<Employee, String>() { 141 @Override 142 public String apply(Employee employee) { 143 return employee.getName(); 144 } 145 }; 146 // lambda 147 Function<Employee,String> func2 = e -> e.getName(); 148 // 方法引用 149 Function<Employee,String> func3 = Employee::getName; 150 151 System.out.println(func1.apply(employee)); 152 System.out.println(func2.apply(employee)); 153 System.out.println(func3.apply(employee)); 154 } 155 }View Code