知识屋:更实用的电脑技术知识网站
所在位置:首页 > 教育

让初学者会写Lambda表达式

发表时间:2022-03-26来源:网络

Lambda表达式

Java 8的一个大亮点是引入Lambda表达式(匿名函数),使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。可以使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。

函数式接口

Java8的新引入,包含函数式的设计,接口都有**@FunctionalInterface的注解**。就像这个注解的注释说明一样,它注解在接口层面,且注解的接口要有且仅有一个抽象方法

Lambda表达式学习

直接看代码,我就用多线程的代码举栗子一步一步看Lambda表达式的推导:
看代码:

不使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("断剑重铸之日,骑士归来之时"); } }).start(); } } 运行结果:


这个代码相信小伙伴们很容易看懂。
接下来是使用Lambda表达式了,首先我们看下Lambda表达式的格式:

()->->:被称为Lambda操作符。左边:Lambda形参列表(接口中的抽象方法的形参列表)右边:Lambda体(重写接口的抽象方法的方法体)

Lambda表达式的本质就是:作为接口的实例

使用Lambda表达式

public class TestLambda { public static void main(String[] args) { new Thread(() -> { System.out.println("断剑重铸之日,骑士归来之时"); }).start(); }

这是Lambda表达式后的代码,基本上只保留的重写接口方法的方法体,
因为这个方法体中只有一句代码,所以可以把{}去掉。

使用Lambda表达式(最终版)

public class TestLambda { public static void main(String[] args) { new Thread(() -> System.out.println("断剑重铸之日,骑士归来之时")).start(); }

是不是强大到可怕?是不是简单到可怕?是不是清晰明了重点突出到可怕?这就是Lambda表达式的可怕之处,用极少的代码完成了之前一个类做的事情!能够代替实现函数式接口的匿名内部类。

关于Lambda的使用:

1、无参无返回值且只有一条执行语句:

这个就是上边那个例子

不使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("断剑重铸之日,骑士归来之时"); } }).start(); } }

使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { new Thread(() -> System.out.println("断剑重铸之日,骑士归来之时")).start(); } 运行结果是一样的:

2、有多条执行语句(不能省略{} ):

不使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("断剑重铸之日,骑士归来之时"); System.out.println("时间不在于你拥有多少,而在于你怎样使用它"); } }).start(); } }

使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { new Thread(() -> { System.out.println("断剑重铸之日,骑士归来之时"); System.out.println("时间不在于你拥有多少,而在于你怎样使用它"); }).start(); } }

2、只有1个参数无返回值:

不使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { Consumer con1 = new Consumer() { @Override public void accept(String s) { System.out.println(s); } }; con1.accept("无形之刃,最为致命"); } }

使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { //数据类型可以省略,因为可以由编译器去推断 Consumer con2 = (String s) -> System.out.println(s); con2.accept("无形之刃,最为致命"); //只有一个参数()也可以省略 Consumer con3 = s -> System.out.println(s); con2.accept("无形之刃,最为致命"); } }

3、有两个或两个以上的参数,且有返回值

使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { new Thread(() -> { System.out.println("断剑重铸之日,骑士归来之时"); System.out.println("时间不在于你拥有多少,而在于你怎样使用它"); }).start(); } }

不使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { Comparator com1 = new Comparator() { @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } }; System.out.println(com1.compare(12, 21)); } }

使用Lambda表达式:

public class TestLambda { public static void main(String[] args) { Comparator com2 = (o1,o2) -> { return o1.compareTo(o2); }; System.out.println(com2.compare(6, 2)); //注意:return和{}要一起省略 Comparator com3 = (o1,o2) -> o1.compareTo(o2); System.out.println(com3.compare(6, 2)); } }

以上就是对Lambda表达式的基本的使用。

接下来简单了解一下方法引用

方法引用

方法引用是Lambda表达式的一个简化写法。所引用的方法其实是Lambda表达式的方法体的实现,其语法结构为:

ObjectRef::methodName

左边可以是类名或者实例名,中间是方法引用符号”::”,右边是相应的方法名。

public class ReferenceTest { public static void main(String[] args) { Converter converter=new Converter() { @Override public Integer convert(String from) { return ReferenceTest.StringToInt(from); } }; converter.convert("120"); } //函数式接口 @FunctionalInterface interface Converter{ T convert(F from); } public static int StringToInt(String from) { return Integer.valueOf(from); } }

这时候如果用静态引用会使的代码更加简洁:

Converter converter = ReferenceTest::StringToInt; converter.convert("120");

方法引用我们可以把它看做是 仅仅调用特定方法的Lambda的一种快捷写法。
实例如下:

(Apple a) -> a.getWeight() Apple::getWeight () -> Thread.currentThread().dumpStack() Thread.currentThread()::dumpStack (str, i) -> str.substring(i) String::substring (String s) -> System.out.println(s) System.out::println

方法引用可以分为三类:

指向静态方法: (args) -> ClassName.staticMethod(args) //可以写成 ClassName::staticMethod 指向实例对象的任意方法(arg0是ClassName类型的): (arg0, rest) -> arg0.instanceMethod(rest) //可以写成 ClassName::instanceMethod 指向实例对象的属性的方法引用: (args) -> expr.instanceMethod(args) //可以写成 expr::instanceMethod
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜