Lambda表达式及方法引用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_32099833/article/details/102613009

Lambda表达式

在JDK8以前,方法能接收的参数都是变量,JDK8之后,支持将函数作为参数传递。

/**
 * @Description: 接口
 */
@FunctionalInterface
public interface Simple {
	void callback();
}

JDK8之前

/**
 * @Description: 客户端测试
 */
public class Client {
	public static void main(String[] args) {
		Simple simple = new Simple() {
			@Override
			public void callback() {
				System.out.println("java7 callback...");
			}
		};
		simple.callback();
		System.out.println(simple.getClass().getName());
	}
}
输出:
java7 callback...
com.ch.java8.lambda.Client$1

创建匿名内部类,实现接口方法,然后调用。

“匿名”是针对开发者而言,对于JVM来说,匿名内部类 仍然有名字。

JDK8

/**
 * @Description: 客户端测试
 */
public class Client {
	public static void main(String[] args) {
		simple = () -> System.out.println("lambda callback...");
		simple.callback();
		System.out.println(simple.getClass().getName());
	}
}
输出:
lambda callback...
com.ch.java8.lambda.Client$$Lambda$1/1490180672

匿名内部类和使用lambda表达式生成的类名有差异。

函数式接口

有且仅有一个抽象方法的普通接口。

Lambda表达式也是实现了接口的抽象方法,而且是接口中唯一的抽象方法,对于含有多个抽象方法的接口,就不能使用Lambda表达式了。

要将一个接口声明为函数式接口,需要在接口中加以下注解:

@FunctionalInterface

在JDK8中,内置了很多函数式接口,可以方便我们直接使用。

详见包路径:java.util.function。

常用的接口
  • Supplier 生产者
    无参数,返回结果。

  • Consumer 消费者
    接收一个入参,不返回结果。

  • Function 普通函数
    接收一个入参,返回结果。

  • Predicate 断言
    接收一个入参,返回布尔值。

Java8提供这些函数式接口,就是为了我们使用Lambda表达式的时候方便,无需自己再去单独定义函数式接口。

接口的默认、静态方法

JDK8之前,接口中只能定义抽象方法,如果接口新增方法,需要修改所有的实现类。
静态方法也只能写在类中,不能定义在接口中。

JDK8中,接口可以有默认方法、静态方法。

/**
 * @Description: 简单接口
 */
@FunctionalInterface
public interface Simple {
	void callback();

    //默认方法
	default void defaultFun(){
		System.out.println("default function...");
	}
	
	//静态方法
	static void staticFun(){
		System.out.println("static function...");
	}
}
/**
 * @Description: 客户端测试
 */
public class Client {
	public static void main(String[] args) {
		Simple simple = () -> System.out.println("lambda callback...");
		simple.defaultFun();
		Simple.staticFun();
	}
}
输出:
default function...
static function...

默认方法通过实例调用,子类可以选择覆盖默认方法。

静态方法通过类调用。

方法引用

自己不实现具体的方法,让JVM引用其他的方法。

/**
 * @Description: 方法引用
 */
public class FunQuote {
	public static void main(String[] args) {
		Consumer<String> consumer = (s) -> System.out.println(s);
		consumer.accept("admin");
		
		//方法引用
		consumer = System.out::println;
		consumer.accept("Lisa");
	}
}
输出:
admin
Lisa

被引用的方法必须与函数式接口中的抽象方法:返回值和形参列表一致。

静态引用

类名::静态方法名

/**
 * @Description: 静态引用
 */
public class FunQuote {
	public static void main(String[] args) {
		//静态引用
		Consumer<String> consumer = FunQuote::staticQuote;
		consumer.accept("admin");
	}

	public static void staticQuote(String s){
		System.out.println("静态引用:" + s);
	}
}
输出:
静态引用:admin

实例引用

对象::实例方法名
/**
 * @Description: 对象::实例方法引用
 */
public class FunQuote {
	public static void main(String[] args) {
		//对象::实例方法引用
		Consumer<String> consumer = new FunQuote()::quote;
		consumer.accept("admin");
	}

	public void quote(String s){
		System.out.println("对象引用:" + s);
	}
}
输出:
对象引用:admin
类名::实例方法名
/**
 * @Description: 类名::实例方法引用
 */
public class FunQuote {
	public static void main(String[] args) {
		//类名::实例方法引用
		Function<String, String> function = String::toUpperCase;
		String apply = function.apply("admin");
		System.out.println(apply);
	}
}
输出:
ADMIN

引用构造器

/**
 * @Description: 引用构造器
 */
@Data
public class ConstructorQuote {
	private String name;

	public ConstructorQuote(String name){
		this.name = name;
	}

	public static void main(String[] args) {
		Function<String, ConstructorQuote> function = ConstructorQuote::new;
		ConstructorQuote quote = function.apply("admin");
		System.out.println(quote.name);
	}
}
输出:admin

引用数组

/**
 * @Description: 数组引用
 */
public class ArrayQuote {
	public static void main(String[] args) {
		Function<Integer,String[]> function = String[]::new;
		String[] apply = function.apply(10);
		System.out.println(apply.length);
	}
}
输出:10

猜你喜欢

转载自blog.csdn.net/qq_32099833/article/details/102613009