day26 java lambda
最编程
2024-06-23 21:56:30
...
lambda
lambda表达式 :对匿名内部类的对象的一种简写 lambda表达式的格式 : (形参列表) -> {方法体} 说明 : -> : lambda操作符
例::Comparator
原代码:
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return 0;
}
});
lambda可以写为:
//lambda表达式(本质就是匿名内部类的对象 - 只不过是对匿名内部类的对象的一种简写)
Comparator<Integer> c2 = (Integer o1, Integer o2) -> {
return 0;
};
Collections.sort(list,c2);
进一步缩写
* 当{Lambda体}中只有一句语句时,可以省略{}和{;} * 当{Lambda体}中只有一句语句时,并且这个语句还是一个return语句, 那么{、return、;}三者可以省略。它们三要么一起省略,要么都不省略。 * 当Lambda表达式(形参列表)的类型已知,获取根据泛型规则可以自动推断, 那么(形参列表)的数据类型可以省略。 * 当Lambda表达式(形参列表)的形参个数只有一个,并且类型已知或可以自动推断, 则形参的数据类型和()可以一起省略,但是形参名不能省略。 * 当Lambda表达式(形参列表)是空参时,()不能省略
例1:
Collections.sort(list,(Integer o1, Integer o2) -> {
return 0;
});
//=====================
Collections.sort(list,(Integer o1, Integer o2) -> 0);
例2:
Comparator<Integer> c3 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
};
//当Lambda表达式(形参列表)的类型已知,获取根据泛型规则可以自动推断,那么(形参列表)的数据类型可以省略。
//lambda
Comparator<Integer> c4 = (o1,o2) -> o1 - o2;
函数式接口:
只有一个抽象方法的接口叫作函数式接口
如果有和Object类中一样的方法的抽象方法也可以,因为所有类都是Object类中的子类,继承了其所有方法只用看其其他抽象方法就好。
说明:
1.lambda表达式只能是函数式接口
2.函数式接口中只能一个抽象方法(如果有和Object类中一样的方法的抽象方法也可以)
3.函数式接口中可以有默认方法和静态方法(也可以有常量)
4.可以在接口上使用注解@FunctionalInterface判断接口是否为函数式接口
例:下面的接口不能使用lambda表达式 因为不是一个函数式接口
//@FunctionalInterface - 报错因为不是函数式接口
interface MyInterface<T>{
void say(T t,T t2);
void show(T t);
}
方法的引用对
lambda表达式的进一步简化
当Lambda表达式满足一些特殊的情况时,还可以再简化: (1)Lambda体只有一句语句,并且是通过调用一个对象的/类现有的方法来完成的 (2)并且Lambda表达式的形参正好全部用上,Lambda体中没有额外的数据参与 方法的引用的格式 实例对象名::实例方法 类名::静态方法 类名::实例方法
例1:类名::实例方法
@Test
public void test4(){
//匿名对部类的对象
new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//比较两个字串的内容
/*
public int compareTo(String anotherString) {
}
*/
return o1.compareTo(o2);
}
};
//lambda表达式
Comparator<String> s = (o1,o2) -> o1.compareTo(o2);
//方法的引用
Comparator<String> s2 = String::compareTo;
例2:实例对象名::实例方法
@Test
public void test3(){
//匿名内部类的对象
new Consumer<String>() {
@Override
public void accept(String s) {
/*
public void println(String x) {
}
*/
PrintStream ps = System.out;
ps.println(s);
}
};
//lambda表达式
Consumer<String> c = s -> System.out.println(s);
//方法的引用
Consumer<String> c2 = System.out::println;
类的引用和数组的引用
public class LambdaTest2 {
/*
类的引用:
类名::new
*/
@Test
public void test(){
//匿名内部类的对象
new Function<Integer, Person>() {
@Override
public Person apply(Integer integer) {
//1.new的对象正好是抽象方法的返回值类型 2.抽象方法的形参正好是构造器要传的实参
return new Person(integer);
}
};
//lambda表达式
Function<Integer, Person> f = i -> new Person(i);
//类的引用
Function<Integer, Person> f2 = Person::new;
}
/*
数组的引用:
数组的类型::new
*/
@Test
public void test2(){
//匿名内部类的对象
new Function<Integer, int[]>() {
@Override
public int[] apply(Integer integer) {
//1.创建的数组正好是抽象方法的返回值类型 2.抽象方法的形参正好是数组的长度
return new int[integer];
}
};
//lambda表达式
Function<Integer, int[]> f = i -> new int[i];
//数组的引用
Function<Integer, int[]> f2 = int[] :: new;
}
}
class Person{
public Person(int a){
System.out.println("public Person(int a)");
}
}
推荐阅读