Lambda表达式使用
1、举例
Comparator<Integer> compara2 = (num1, num2) -> Integer.compare(num1, num2);
2、格式
‘->’ 符号是lambda操作符,又叫箭头操作符
-> 左边:lambda的形参列表(实际就是接口中抽象方法的形参列表)
->右边:lambda体(实际是重写的抽象方法的方法体)
3、lambda表达式的使用
(1)无参无返回值
Runnable r1 = () -> {
System.out.println("Hello World");
};
(2)一个参数,没有返回值
// accpet是Consumer接口的抽象方法
Consumer<String> comsumer1 = (String str) -> {
System.out.println(str);
};
comsumer1.accept("重写Consumer接口的抽象方法");
(3)数据类型可以省略,因为可以由编译器推断得出,称为“类型推断”,与List<String> list = new ArrayList<>();相似
Consumer<String> consumer3 = (str) -> {
System.out.println(str);
};
consumer3.accept("类型推断Consumer接口的泛型");
(4)Lambda表达式只有一个参数时,形参的小括号可以省略
Consumer<String> consumer = str -> {
System.out.println(str);
};
consumer.accept("只有一个参数可以省略括号");
(5)Lambda需要两个以上的参数,多条执行语句,并且有返回值
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer n1, Integer n2) {
Integer sum = sum(n1, n2);
System.out.println(sum);
Integer sub = sub(n1, n2);
System.out.println(sub);
return n1.compareTo(n2);
}
};
int compare = comparator.compare(100, 50);
System.out.println(compare);
// lambda写法
Comparator<Integer> comparator1 = (Integer n1, Integer n2) -> {
Integer sum = sum(n1, n2);
System.out.println(sum);
Integer sub = sub(n1, n2);
System.out.println(sub);
return n1.compareTo(n2);
};
(6)当lambda体只有一条语句时,return与大括号若有,都可以省略
Comparator<Integer> comparator = (n1, n2) -> n1.compareTo(n2);
或者
Consumer<String> comsumer = str -> System.out.println(str)
4、Lambda表达式本质
作为函数式接口的实例
如果有且仅有一个抽象方法的接口,则此接口就称为函数式接口; 函数式接口就是可 以适用于Lambda使用的接口 ,意味着如果需要使用lambda表达式,就必须是函数式接口,所以以前用匿名实现类表示的现在都可以用Lambda表达式来写
例如:
总结
‘->’lambda符号左侧形参列表类型可以省略(类型推断), 如果lambda形参列表只有一个参数,其()也可以删除;
'->'lambda符号右侧的lambda体应该使用一对{}包裹,如果lambda体类只有一条执行语句,则可以省略return和{}(return和{}需要同时省略)
函数式接口
Consumer:消费型接口,内有抽象方法—void accept(T t)
Supplier:生产型接口(供给型),内有抽象方法—T get();
Function<T, R>:函数型接口,内有抽象方法—R apply(T t)
Predicate:断言型接口,内有抽象方法—boolean test(T t)
Consumer例子
public void testConsumer() {
// 消费型接口Consumer void accept(T t)
happyTime(new BigDecimal(500), new Consumer<BigDecimal>() {
@Override
public void accept(BigDecimal bigDecimal) {
System.out.println("花费了" + bigDecimal + "元");
}
});
// lambda写法
happyTime(new BigDecimal(500), money -> {
System.out.println("花费了" + money + "元");
});
}
public void happyTime(BigDecimal money, Consumer<BigDecimal> consumer) {
consumer.accept(money);
}
Predicate例子
public List<String> testPredicate() {
// 断言型接口 boolean test(T t)
List<String> stringList = Arrays.asList("北京", "南京", "天津", "上海", "东京", "西京", "普京");
List<String> filterString = filterString(stringList, new Predicate<String>() {
@Override
public boolean test(String str) {
return str.contains("京");
}
});
filterString = filterString(stringList, (str) -> {
return str.contains("京");
});
return filterString;
}
/**
* 根据给定的规则过滤集合中的字符串,此规则由实现Predicate的抽象方法决定
*
* @param stringList
* @param predicate
* @return
*/
public List<String> filterString(List<String> stringList, Predicate<String> predicate) {
List<String> filterString = new ArrayList<>();
for (String str : stringList) {
if (predicate.test(str)) {
filterString.add(str);
}
}
return filterString;
}
方法引用
方法引用的使用
-
1.使用情景:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用
-
2.方法引用,本质上是Lambda表达式,而Lambda表达式作为函数式接口的实例,所以方法引用,也是函数式接口的实例
-
3.使用格式: 类(或对象):: 方法名
-
4.具体使用分为三种情况:
-
对象::非静态方法
-
类::静态方法
-
类::非静态方法
-
-
5.方法引用的要求,要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同
情况一:对象::实例方法
// Consumer中的void accept(T t)
// PrintStream中的void println(T t)
PrintStream printStream = System.out;
Consumer<String> consumer1 = printStream::println;
consumer1.accept("方法引用");
/**
* Supplier的T get()
* Employee中的String getName()
*/
public void test2() {
System.out.println("===lambda表达式====");
Employee employee = new Employee(1001, "马化腾", 34, 60000);
Supplier<String> supplier = () -> {
return employee.getName();
};
supplier = () -> employee.getName();
System.out.println(supplier.get());
System.out.println("===方法引用===");
Supplier<String> supplier2 = employee::getName;
System.out.println(supplier2.get());
}
情况二:类::静态方法
/**
* 情况二:类::静态方法
* Comparator中的int compare(T t1, T t2)
* Integer中的int compare(T t1, T t2)
*/
public void test3() {
// lambda表达式
Comparator<Integer> comparator = (t1, t2) -> {
return Integer.compare(t1, t2);
};
comparator = (t1, t2) -> Integer.compare(t1, t2);
int compare = comparator.compare(100, 20);
System.out.println(compare);
// 方法引用
Comparator<Integer> comparator1 = Integer::compare;
int compare1 = comparator1.compare(100, 20);
System.out.println(compare1);
}
// 有参有返回值
// Function中的R apply(T t)
// Math中的Long round(Double d)
public void test4() {
// lambda表达式写法
Function<Double, Long> function = (d) -> {
return Math.round(d);
};
function = d -> Math.round(d);
System.out.println(function.apply(1.9));
// 方法引用
Function<Double, Long> function1 = Math::round;
System.out.println(function1.apply(1.9));
}
情况三:类::实例方法
// 情况三:类::实例方法
// Comparator中的int compare(T t1, T t2)
// String中的int t1.compareTo(T t2)
public void test5() {
// Lambda表达式
Comparator<String> comparator = (s1, s2) -> s1.compareTo(s2);
int compare = comparator.compare("abc", "abd");
System.out.println(compare);
// 方法引用
Comparator<String> comparator1 = String::compareTo;
int compare1 = comparator1.compare("abc", "abd");
System.out.println(compare1);
}
/**
* BiPredicate中的boolean test(T t1, T t2)
* Stirng中的boolean t1.equals(t2)
*/
public void test6() {
// lambda表达式
BiPredicate<String, String> predicate = (str1, str2) -> str1.equals(str2);
boolean result = predicate.test("aaa", "222");
System.out.println(result);
// 方法引用
BiPredicate<String, String> predicate1 = String::equals;
result = predicate1.test("aaa", "222");
System.out.println(result);
}
// Function中的R apply(T t)
// Employee中的String getName()
public void test7() {
// Lambda表达式
Function<Employee, String> function = employee -> employee.getName();
String name = function.apply(new Employee(1001, "马化腾", 34, 60000));
System.out.println(name);
// 方法引用
Function<Employee, String> function1 = Employee::getName;
name = function1.apply(new Employee(1001, "mayun", 34, 60000));
System.out.println(name);
}
构造器引用
和方法引用类似
// 构造器引用
public void test1() {
// lambda表达式
Supplier<Employee> supplier = () -> new Employee();
// 构造器引用
Supplier<Employee> supplier1 = Employee::new;
// 调用Supplier接口的抽象方法get()
Employee employee = supplier1.get();
System.out.println(employee);
}
// Function中的R apply(T t)
public void test2() {
// Lambda表达式
Function<Integer, Employee> function = id -> new Employee(id);
Employee employee = function.apply(12);
System.out.println(employee);
// 构造器引用
Function<Integer, Employee> function1 = Employee::new;
Employee employee1 = function1.apply(50);
System.out.println(employee1);
}
// BiFunction中的 R apply(T t, R r)
public void test3() {
BiFunction<Integer, String, Employee> biFunction = Employee::new;
Employee employee = biFunction.apply(20, "zhangsan");
System.out.println(employee);
}
数组引用
// 数组引用
// Function中的R apply(T t)
public void test4() {
// lambda表达式
Function<Integer, String[]> function = length -> new String[length];
String[] strings = function.apply(5);
System.out.println(Arrays.toString(strings));
// 数组引用
Function<Integer, String[]> function1 = String[] ::new;
String[] strings1 = function1.apply(6);
System.out.println(Arrays.toString(strings1));
}