JAVA SE面向对象编程之Lambda
不知道使用的感觉好高大上,使用的感觉也就那样(编程容易)。
简单描述,Lambda运行使用简洁的代码来创建只有一个抽象方法的接口的实例(符合这种要求的接口我们把它们叫做函数式接口,JAVA8提供了一些函数式接口可以参考https://www.cnblogs.com/sxrtb/p/12685052.html)
简单使用例子来说明
public class ConsumerTest { public static void main(String[] args) { ProcessArr processArr = new ProcessArr(); int[] intarr = new int[]{1,2,3,4,6,5}; processArr.process(intarr,(int[] t)-> { for (int ti:t) { System.out.println(ti); } } ); } } class ProcessArr{ public void process(int[] target ,ConsumerInterface consumerInterface){ consumerInterFact.accpet(target); } } interface ConsumerInterface{ void accpet(int[] target); }
在这个例子中,就是将使用匿名内部类的地方使用了Lambda替换
Lambda使用:
参数列表,用括号()括起来,若只有一个参数,可以省略括号
->
方法体,用花括号{}括起来,只有一条语句,则可以省略{},且此时可以省略return字段
方法体中只有一条语句时,可以使用方法引用和构造器引用(就是一些简编代码的编程方式)
1.引用类方法
public class ClassMethodRefTest { public static void main(String[] args) { Converter classMethodRef = Integer::valueOf; //Converter classMethodRef = t -> Integer.valueOf(t);相当于上面的编程 int a = classMethodRef.Convert("123"); System.out.println(a); } } interface Converter{ int Convert(String s); }
2.对象引用实例方法
public class InstanceMethodRefTest { public static void main(String[] args) { Converter converter = "abcd"::indexOf; //Converter converter = t -> "abcd".indexOf(t);相当于上面的编程 int s = converter.Convert("b"); System.out.println(s); } } interface Converter{ int Convert(String s); }
3.类引用实例方法
public class ClassInstanceMethodRefTest { public static void main(String[] args) { ConverterT converter = String::substring; //ConverterT converter = (a,b,c) ->a.substring(b,c);相当于上面的编程 String s = converter.sub("abcdef",1,3); System.out.println(s); } } interface ConverterT{ String sub(String a,int b,int c); }
4.应用构造器
简单说一下,若函数式接口的抽象方法返回一个对象,而该方法中的参数和对象所在类中定义的构造器有相同的形参列表,则直接使用返回对象的名称::new就行
刚开始看的或,可能会感觉不好理解,简单说一下我是怎么理解的吧
1.先看返回参数,若函数式接口的返回值和我们知道的任意方法的返回值相同,首先我们就可以考虑用我们知道的方法来完成我们抽象方法的实现
2.参数填坑,将函数式接口中的方法参数填写到我们知道的方法的对象(若调用类方法,则不需要对象),方法列表,若刚好能放进去,恭喜你,你可以使用引用的方式完成Lambda的编写了
若明白了这个点,也会发现一个有趣的问题。
public class LambdaT { public static void main(String[] args) { AInterface aInterface = A::test1; aInterface.printString(new A(),1,2); } } class A{ public void test1(int b,int c){ System.out.println("test1 b c isntance"); } } interface AInterface{ public void printString(A a,int b,int c); }
public class LambdaT { public static void main(String[] args) { AInterface aInterface = A::test1; aInterface.printString(new A(),1,2); } } class A{ public static void test1(A a,int b,int c){ System.out.println("test1 a b c static"); } } interface AInterface{ public void printString(A a,int b,int c); }
当然,顺着这个思路,其实大家要是细看的话(或者说自己写了的话),会发现例子2和例子3有点相似,我们这里来改变例子2,让它和例子3相同
public class InstanceMethodRefTest { public static void main(String[] args) { Converter converter = String::indexOf; //Converter converter = (t,tt) -> t.indexOf(tt);相当于上面的编程 int s = converter.Convert("abcd","b"); System.out.println(s); } } interface Converter{ int Convert(String s,String ss); }
所以总结来看,其实例子1,例子2和例子3其实时一样的
5.Lambda和匿名内部类的区别
Lambda不能调用接口中的默认方法,但是匿名内部类可以(个人绝对知道这点就可以了,其他的就是Lambda受限于函数式接口带来的)
posted on 2020-04-12 15:46 xingshouzhan 阅读(176) 评论(0) 编辑 收藏 举报