Lambda 表达式在Java 8 语言中引入了一个新的语法元素和操作符。这个操作符为 “->” , 该操作符被称为 Lambda 操作符或箭头操作符。它将 Lambda 分为两个部分:
左侧:指定了 Lambda 表达式需要的参数列表
右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能。
语法:
1、无参,无返回值
() -> {Lambda体};
当Lambda体只有一句话时,可以简写为: () -> Lambda体;
2、有参,无返回值 消费型
(形参列表) -> {语句体;};
interface Inter2<T>{ void test(T t); } @Test public void testNoReturnValueHasOneParam2(){ Inter2<String> i1 = (String str) -> {System.out.println(str);}; i1.test("hello"); Inter2<String> i2 = (str) -> {System.out.println(str);}; i2.test("hello"); Inter2<String> i3 = str -> {System.out.println(str);}; i3.test("hello"); }
3、无参,有返回值
() -> {Lambda体}
interface Inter5{ String test(); } @Test public void testHasReturnValueNoParam(){ Inter5 i1 = () -> { String s = getInfo(); return s; }; String test1 = i1.test(); System.out.println(test1); Inter5 i2 = () -> getInfo(); String test2 = i2.test(); System.out.println(test2); Inter5 i3 = () -> "hello"; String test3 = i3.test(); System.out.println(test3); } public String getInfo(){ return "atguigu"; }
4、有参,有返回值
(形参列表) -> {Lambda体}
public interface Comparator<T> { int compare(T o1, T o2); } @Test public void testHasReturnValueHasParam(){ Comparator<String> c1 = (String str1,String str2) -> { return str1.length() - str2.length(); }; c1.compare("hello", "java"); Comparator<String> c2 = (str1,str2) -> str1.length() - str2.length(); c2.compare("hello", "java"); }
函数式接口
函数式接口其实本质上还是一个接口,但是它是一种特殊的接口:SAM类型的接口(Single Abstract Method)。定义了这种类型的接口,使得以其为参数的方法,可以在调用时,使用一个lambda表达式作为参数。从另一个方面说,一旦我们调用某方法,可以传入lambda表达式作为参数,则这个方法的参数类型,必定是一个函数式的接口,这个类型必定会使用@FunctionalInterface进行修饰。
从SAM原则上讲,这个接口中,只能有一个函数(方法)需要被实现,但是也可以有如下例外:
1. 默认方法与静态方法并不影响函数式接口的契约,可以任意使用
2. 可以有 Object 中覆盖的方法,也就是 equals,toString,hashcode等方法。
JDK中以前所有的函数式接口都已经使用 @FunctionalInterface 定义,可以通过查看JDK源码来确认,以下附JDK 8之前已有的函数式接口:
java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator
java.io.FileFilter
java.lang.reflect.InvocationHandler
......等