这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战
lambda表达式类型推断
在 lambda的方法引用一文中juejin.cn/post/699999… 已经说明了 lambda是个匿名方法,最后返回一个实现了指定接口的对象,所以你就要说明实现的是哪个接口,否则会报错这就是类型推断
类型推断有多种方式
@FunctionalInterface
interface IMath{
int add(int x,int y);
}
public class TypeDemo {
public static void main(String[] args) {
//变量类型定义
IMath lambda = (x,y)->x+y;
//数组里
IMath[]lambdas = {(x,y)->x+y};
//强制类型转换
Object lambda2 = (IMath)(x,y)->x+y;
//通过返回类型
IMath createLambda =createLambda();
TypeDemo demo = new TypeDemo();
demo.test((x, y) -> x+y);
}
public void test(IMath math){
}
}
以上就是一般来说的方式
在IMath下新建一个接口IMath2
@FunctionalInterface
interface IMath2{
int sub(int x,int y);
}
重载一下 test
public void test(IMath math){
}
public void test(IMath2 math){
}
此时发现了一个问题
重载了 test引发的时候确不指出是哪个,所以报了错 这样的时候我们就要指定类型
//当不确定性的时候,使用强制类型转换
demo.test((IMath2) (x, y) -> x+y);
lambda表达式变量引用、
既然lambda是匿名类,那么引用过程和 匿名类是同样的。 先看代码
public class VarDemo {
public static void main(String[] args) {
String str = "这个string不可以在修改";
str = "44944";
Consumer<String> consumer = s-> System.out.println(s+str);
consumer.accept("1211");
}
}
为什么这个str 不可以修改呢 ?
有些用过java 8以前的版本的大佬应该知道从前匿名类引用外面的对象要加上 final ,但是java8默认给你加上了,所以这里不写 final 也无所谓
那我们就不理解了,为什么要加上 final
首先想个问题 Java传参数是传值,还是传引用? 答案是传值。 我们再看看另一坨代码
List<String> list = new ArrayList<>(); //list 记作 A
Consumer<String> consumer2 = s-> System.out.println(s+list);
consumer2.accept("1234");
当代码这么写,就更容易解释为什么是值引用,就会导致不可修改
上面 list 在 C 处调用 的过程中, A -> B -> C
如果值改变了, 也就是说 A -> D ,但是此时因为是值引用,导致 B ->C
同样调用一个 list 却得出了不同的值。
如果是传引用 那么就是 C -> B -> A ,A怎么换都无所谓
级联表达式 柯里化
什么是级联表达式?
级联表达式是多个箭头的表达式 x->y -> x+ y
以上的表达式代表什么意思呢? lambda表达式 左面是输入右边是输出。 先看第一个-> ,输入了 x 输出了 y->x+y;所以这是个 Function 第二个 -> ,输入了 y 输出了 x+y ,所以这也是个 Function 最后 是个 x+ y ,所以可能是 数字或字符串,我们先当作 数字
public static void main(String[] args) {
Function<Integer,Function<Integer,Integer>>function = x->y ->x+y;
System.out.println(function.apply(2).apply(3));
}
柯里化:把多个参数的函数转换为只有一个参数的函数 柯里化的意义:把函数标准化 高阶函数:返回函数的函数
柯里化之前
Function<Integer,Function<Integer,Function<Integer,Integer>>> fun2 = x->y->z -> x+y+z;
System.out.println(fun2.apply(2).apply(3).apply(4));
那岂不是越来越多的函数就代表越来越长
柯里化之后。。。
Function f = fun2;
for (int i=0;i<nums.length;i++){
if (f instanceof Function){
Object obj = f.apply(nums[i]);
if (obj instanceof Function){
f = (Function) obj;
}else {
System.out.println("调用结束:结果为"+obj);
}
}
}
调用的是一个函数,返回的依旧是要给函数。