一、Lambda表达式
Lambda表达式可以认为是一种特殊的匿名内部类。
1、基本语法
([形参列表,不带数据类型]) -> {
//执行语句,方法体
[return ...;]
};
2、注意点
1、如果形参列表是空的,只需要保留()即可。
2、如果没有返回值,只需要在{}写执行语句即可。
3、如果接口的抽象方法只有一个形参,()可以省略,只需要参数的名称即可。
4、如果执行语句只有一行,可以省略{},但是如果有返回值的时候,必须省略return关键字。
5、形参列表的数据类型自动推断,只要参数名称即可,且参数名称自己任意给出。
6、和匿名内部类一样,若访问局部变量,要求局部变量必须是final。
二、引用方法
1、引用类方法
自动把调用方法时的参数,全部传递给引用的方法
<函数式接口> <变量名> = <类名>::<类方法名>;
//自动将[实参列表]全部传递给引用的类方法
<变量名>.<接口方法名>([实参列表]);
2、引用实例方法
自动把调用方法时的参数,全部传递给引用的方法
<函数式接口> <变量名> = <实例对象名>::<实例方法名>;
//自动将[实参列表]全部传递给引用的实例方法
<变量名>.<接口方法名>([实参列表]);
3、通过类引用实例方法(难点)
定义/调用接口方法的时候,需要多一个参数,并且参数的类型和引用实例方法的类型保持一致。
把第一个参数作为引用的实例,后面的每个参数全部传递给引用的方法。
interface <函数式接口>{
<返回值> <方法名>(<类名> <名称> [,其它的参数...])
}
<函数式接口> <变量名> = <类名>::<实例方法名>;
<变量名>.<方法名>(<类名的实例>[,其它的参数...]);
三、引用构造器
1、把方法的所有参数全部传递给引用的构造器,根据参数类型决定调用哪个构造器
<类名> :: new;
四、代码描述
1、CloseDoor.java
/**
* @Title: CloseDoor.java
* @Package com.lty.java8.lambda2
* @Description: TODO
* @author Liu
* @date 2017年12月19日 下午2:59:16
* @version V1.0
*/
package com.lty.java8.lambda2;
@FunctionalInterface
interface Closable{
void close();
}
/**
* @ClassName: CloseDoor
* @Description: TODO
* @author Liu
* @date 2017年12月19日 下午2:59:16
*
*/
public class CloseDoor {
public void doClose(Closable c){
System.out.println(c);
c.close();
}
public static void main(String[] args) {
CloseDoor closeDoor = new CloseDoor();
closeDoor.doClose(new Closable(){
@Override
public void close() {
System.out.println("使用匿名内部类实现");
}
});
closeDoor.doClose( () -> System.out.println("Lambda表达式实现"));
}
}
2、TestLambda.java
/**
* @Title: TestLambda.java
* @Package com.lty.java8.lambda2
* @Description: TODO
* @author Liu
* @date 2017年12月19日 上午10:49:57
* @version V1.0
*/
package com.lty.java8.lambda2;
//使用Lambda表达式,必须用函数式 接口
interface TestLambdaInterface{
void test();
}
interface TestLambdaInterface2{
void test(String s);
}
interface TestLambdaInterface3{
void test(String s, int i);
}
/**
* @ClassName: TestLambda
* @Description: TODO
* @author Liu
* @date 2017年12月19日 上午10:49:57
*
*/
public class TestLambda {
public static void main(String[] args) {
TestLambdaInterface testLambdaInterface = new TestLambdaInterface(){
@Override
public void test() {
System.out.println("使用匿名内部类实现的抽象方法");
}
};
testLambdaInterface.test();
//右边的类型,会自动根据左边的变量的类型进行推断
TestLambdaInterface testLambdaInterface2 = () -> {
System.out.println("使用Lambda表达式实现的抽象方法");
};
testLambdaInterface2.test();
//省略了{}
TestLambdaInterface testLambdaInterface3 = () -> System.out.println("省略了{}的Lambda表达式实现的抽象方法");
testLambdaInterface3.test();
//有参数的Lambda表达式
TestLambdaInterface2 testLambdaInterface4 = (s) -> System.out.println("s: " + s);
testLambdaInterface4.test("参数值内容...");
//
TestLambdaInterface2 testLambdaInterface5 = s -> System.out.println("s: " + s);
testLambdaInterface5.test("抽象方法只有一个参数,省略了()...");
//抽象方法不只一个参数的时候,()不能省略
TestLambdaInterface3 testLambdaInterface6 = (s,i) -> System.out.println("s: " + s + ",i: " + i);
testLambdaInterface6.test("hello", 9);
}
}
3、TestLambdaReturn.java
/**
* @Title: TestLambdaReturn.java
* @Package com.lty.java8.lambda2
* @Description: TODO
* @author Liu
* @date 2017年12月19日 下午3:14:53
* @version V1.0
*/
package com.lty.java8.lambda2;
@FunctionalInterface
interface LambdaReturn{
int test();
}
/**
* @ClassName: TestLambdaReturn
* @Description: TODO
* @author Liu
* @date 2017年12月19日 下午3:14:53
*
*/
public class TestLambdaReturn {
void returnVal(LambdaReturn lambdaReturn){
int i = lambdaReturn.test();
System.out.println("Lambda返回值: " + i);
}
public static void main(String[] args) {
TestLambdaReturn testLambdaReturn = new TestLambdaReturn();
//如果需要return,但是只有一句,可以省略大括号和return关键字
testLambdaReturn.returnVal(() -> 5);
int k = 3;
testLambdaReturn.returnVal(() -> k);
//和匿名内部类一样,若访问局部变量,要求局部变量必须是final
// k = 8;
// System.out.println(k);
}
}
4、TestMethodRef.java
/**
* @Title: TestMethodRef.java
* @Package com.lty.java8.lambda2
* @Description: TODO
* @author Liu
* @date 2017年12月19日 下午3:33:57
* @version V1.0
*/
package com.lty.java8.lambda2;
import java.io.PrintStream;
import java.util.Arrays;
import com.sun.org.apache.xpath.internal.operations.String;
interface MethodRef{
void test(String s);
}
interface MethodRef2{
void test(int[] array);
}
interface MethodRef3{
void test(PrintStream out, String s);
}
//测试构造器引用
interface MethodRef4{
String test(char[] cs);
}
/**
* @ClassName: TestMethodRef
* @Description: TODO
* @author Liu
* @date 2017年12月19日 下午3:33:57
*
*/
public class TestMethodRef {
/***
* @Title: main
* @Description: TODO
* @param @param args
* @return void
* @throws
*/
public static void main(String[] args) {
MethodRef methodRef = s -> System.out.println(s);
methodRef.test("原生的Lambda表达式");
//使用实例方法引用
MethodRef methodRef2 = System.out :: println;
methodRef2.test("实例方法引用");
//不引用方法排序
// MethodRef2 methodRef4 = o -> Arrays.sort(o);
//能够根据函数式接口的方法参数,推断引用方法的参数数据类型
MethodRef2 methodRef3 = Arrays :: sort;
int[] a = {3,6,1,5,9};
//引用方法排序
methodRef3.test(a);
//引用方法输出
methodRef.test(Arrays.toString(a));
//引用类实例方法
MethodRef3 methodRef4 = PrintStream :: println;
//第二个之后的参数,作为所引用的方法的参数
methodRef4.test(System.out, "引用类实例方法");
System.out.println("-----------------------------");
//引用构造器,根据函数式接口的返回值和参数判断引用哪个构造器
MethodRef4 methodRef5 = String :: new;
String s = methodRef5.test(new char[]{'H','e','y'});
System.out.println(s);
MethodRef4 methodRef6 = cx -> new String(cx);
String string = methodRef6.test(new char[]{'H','a'});
System.out.println(string);
}
}