lambda表达式
lambda表达式是一个可传递的代码块。可以以后执行一次或者多次。在程序运行中我们经常会遇到传递代码段的情况,但是我们一般都是先构造一个对象,然后通过对象调用相应的代码块来实现传递代码块的目的,这个方法十分繁琐,设计师为解决这个问题,就设计出了lambda表达式。
lambda表达式的语法
我们可以参考之前写的方法,可以发现如果方法可以分为方法名,参数和方法主体。lambda表达式就是将方法名省去:
标准情况:
(参数类型1 参数1,参数类型2 参数2,.....,参数类型n 参数n)
—>{方法主体}
lambda表达式就是一个代码块,以及必须传入代码的类型规范。如果表达式只有一句话,可以省去大括号以及return;
(参数类型1 参数1,参数类型2 参数2,.....,参数类型n 参数n)
—>表达式
如果是lambda表达式是无参数的情况时,仍然要提供空括号,就如同无参数方法一样。
()—>{方法主体}
如果可以推导出lambda表达式的参数类型,就可以忽略参数类型。
( 参数1, 参数2,....., 参数n)
—>{方法主体}
如果方法只有一个参数,且这个参数类型是可以推导出来的还可以省略小括号。
参数
—>{方法主体}
在lambda表达式中不需要指定返回类型,其返回类型会在上下文推导出来。
下面的代码实现如何在一个比较器和一个动作监听器中使用lambda表达式。
package com.java.lambda; import java.util.Arrays; import java.util.Date; import javax.swing.JOptionPane; import javax.swing.Timer; public class LambdaTest { public static void main(String[] args) { // TODO Auto-generated method stub String[] planets=new String[] {"Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"}; System.out.println(Arrays.toString(planets)); System.out.println("Sorted in dictionary order:"); Arrays.sort(planets); System.out.println(Arrays.toString(planets)); Arrays.sort(planets, (first,second)->first.length()-second.length()); System.out.println(Arrays.toString(planets)); Timer t=new Timer(1000,event->System.out.println("The time is "+new Date())); t.start(); JOptionPane.showMessageDialog(null, "Quit Program?"); System.exit(0); } }
运行结果如下:
[Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune] Sorted in dictionary order: [Earth, Jupiter, Mars, Mercury, Neptune, Saturn, Uranus, Venus] [Mars, Earth, Venus, Saturn, Uranus, Jupiter, Mercury, Neptune] The time is Thu Feb 07 15:05:03 GMT+08:00 2019 The time is Thu Feb 07 15:05:04 GMT+08:00 2019 The time is Thu Feb 07 15:05:05 GMT+08:00 2019 The time is Thu Feb 07 15:05:06 GMT+08:00 2019 The time is Thu Feb 07 15:05:07 GMT+08:00 2019 The time is Thu Feb 07 15:05:08 GMT+08:00 2019 The time is Thu Feb 07 15:05:09 GMT+08:00 2019
通过分析可以发现,lambda在代码中起到的作用就是直接使用代码块的功能。
函数式接口
Java中已经有很多封装代码块的接口,lambda表达式与这些接口是兼容的。对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口。
可以这么理解,如果有一个接口A是只有一个抽象方法的接口,在某个类引用了这个接口,调用这个方法时,那个方法就会执行lambda这个表达式的体。这样会使代码更加简洁。
方法引用
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法。方法引用提供了一种引用而不执行方法的方式,它需要由兼容的函数式接口构成的目标类型上下文。计算时,方法引用会创建函数式接口的一个实例。简单地说,就是一个Lambda表达式。在Java 8中,我们会使用Lambda表达式创建匿名方法,但是有时候,我们的Lambda表达式可能仅仅调用一个已存在的方法,而不做任何其它事,对于这种情况,通过一个方法名字来引用这个已存在的方法会更加清晰,Java 8的方法引用允许我们这样做。方法引用是一个更加紧凑,易读的Lambda表达式,注意方法引用是一个Lambda表达式,其中方法引用的操作符是双冒号"::"。
主要分为三种情况:
1)object::instanceMethod
2) Class::staticMethod
3) Class::instanceMethod
构造器引用
构造器引用与方法引用很类似,只不过方法名为new。例如,Person::new是Person构造器的一个引用,但是我们这个是并不知道哪一个构造器的,这是要根据上下文才能决定的。
可以用数组类型建立构造器引用,例如int[]::new即等价于x->new int[x];
其实还有一些关于关于lambda的知识,那些我并未完全读懂,等我研究透了,会在这篇博客中加上。