Lambda表达式及对方法和构造器的引用

一、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);
		
		
	}

}

 

转载于:https://my.oschina.net/Howard2016/blog/1592157

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值