6.3.3函数式接口
java中有很多封装代码块的接口,如ActionListener或Comparator。lambad表达式与这些接口是兼容的。
对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambad表达式,这种接口称为函数式接口(functional interface)。
Java中可以声明非抽象方法。
采用Arrays.sort展示函数式接口。它的第二个参数需要一个Compatator实例,Comparator就是只有一个方法的接口。所以可以提供一个lambda表达式:
Arrays.sort(words,(first,second) -> first.length()-second.length());
在底层,Arrays.sort方法会接收实现了Comparator<String>的某个类的对象。在这个对象上调用Compare方法会执行这个lambda表达式的体。这些对象和类的管理完全取决于具体实现,与传统的内联类相比,这样可能要高效很多。最好把lambda表达式看作是一个函数,而不是一个对象,另外要接受lambda表达式可以传递到函数式接口。
lambda表达式可以转换为接口:例
Timer t =new Timer(1000,event-> { System.out.println("At the tone,the time is" + new Date()); Toolkit.getDefaultToolkit().beep(); })
要使用实现了ActionListener接口的类相比,这个代码可读性要好很多。
实际上,在Java中,对lambda表达式所能做的也只是能转换为函数是接口。
不能把lambda表达式赋给类型为Object的变量,Object不是一个函数是接口。
java API在java.util.function包中定义了很多非常通用的函数式接口,其中一个接口BIFunction<T,U,R>描述了参数类型为T和U而且返回类型为R的函数。可以把我们的字符串比较lambda表达式保存在这个类型的变量中。
BiFunction<String,String,Integer> comp
=(first,second) -> first.length( )-second.length();
不过,这对于排序并没有帮助,没有那个Arrays.sort方法想要接收一个Bifunction。类似Comparator的接口往往有一个特定的用途,而不是提供一个有指定参数和返回类型的方法。想要用lambda表达式做某些处理,还是要谨记表达式的用途,为他建立一个特定的函数式借口。
java.util.function包中有一个尤其有用的接口Predicate:
public interface Prediccate<T> { boolean test(T t); }
ArrayList类有一个removeIF方法,他的参数就是一个Predicate。这个接口专门用来处于传递lambda表达式。
下面的语句将从一个数组列表删除所有null值:
list.removeIf(e -> e ==null);