1、函数式接口:只定义了单一抽象方法的接口,用做Lambda表达式的类型java
注解@FunctionalInterface用于Service代表Service接口是一个函数式接口,这里须要强调的是:函数式接口只能有一个抽象方法,而不是只能有一个方法。函数
2、使用default关键字,能够在接口内定义实例方法,这个方法并不是抽象方法,而是拥有特定逻辑的具体实例方法,具体的实现类中不是必须重写默认方法测试
3、Lambda表达式即匿名函数,它是一段没有函数名的函数体,能够做为参数直接传递给相关的调用者.this
4、Lanbda表达式的语法spa
(Type1 param1, Type2 param2, ..., TypeN paramN) -> { statment1; statment2; //............. return statmentM; }
表达式使用 "->"将参数和主体分开, -> 前面是参数部分,后面这是主体部分对象
说明:用正常的函数来讲明接口
Type:是具体参数的类型get
param:是具体参数名编译器
{ }:方法体io
statment:方法体重具体的代码处理逻辑
return:方法体中的返回值
一、lambda表达式没有参数,使用空括号()表示没有参数:
() -> { //..... };
二、lambda表达式只有一个参数,可省略参数括号和参数类型,javac能根据上下文推断出参数类型。
param1 -> { statment1; statment2; //............. return statmentM; }
三、当lambda表达式只包含一条语句时,能够省略大括号{}。
param1 -> statment
四、参数类型省略–绝大多数状况,编译器均可以从上下文环境中推断出lambda表达式的参数类型。
(param1,param2, ..., paramN) -> { statment1; statment2; //............. return statmentM; }
5、方法引用
方法引用是Java8中提出的用来简化Lambda表达式的一种手段,它经过类名和方法名来定位一个静态方法或者实例方法。方法引用使用"::"定义,"::"的前半部分表示类名或者实例名,后半部分表示方法名称,若是是构造器函数,则使用new表示。
一、静态方法引用:ClassName::methodName
List<String> strs = Arrays.asList("aa","bb","cc"); strs.forEach(System.out::println);
输出结果:
class Printer { void print() { System.out.println("instanceRefence::methodName"); } private void printInfo() { //实例方法引用 new Thread(this::print); } } //测试 private void test () { Printer p = new Printer(); p.print(); }
输出结果:
public class Test { class User { String username; User(String username) { this.username = username; } public String getUsername() { return username; } } @FunctionalInterface interface UserFactory<T extends User> { T create(String username); } public static void main(String[] args) { Test t = new Test(); t.test(); } private void test() { UserFactory<User> uf = User::new; List<User> users = new ArrayList<>(); for (int i = 0; i < 5; ++i) { users.add(uf.create("user" + i)); } users.stream().map(User::getUsername).forEach(System.out::println); } }
UserFactory做为User的工厂类,是一个函数式接口。当使用User::new建立接口实例时,系统会根据UserFactory.create()的函数签名选择合适的User构造函数。在建立UsrFactory实例后,对UsrFactory.create()的调用都会委托给User的实际构造函数进行,从而建立User对象实例。User::getUsername表示User类的实例方法。
输出结果: