概念
- 行为参数化:让方法接受多种行为(策略)作为参数,并在内部使用,来完成不同的行为
- 缺失的方法主体随接口提供了(因此就有了默认实现),而不是由实现类提供
2. Lambda 表达式
- Lambda 表达式是一种简洁的语法,用于替换实现函数接口的匿名内部类
- Lambda 表达式允许把函数作为方法参数传递
- 注意:Lambda 表达式不会生成一个单独的内部类文件
总结:Lambda 是一个匿名函数(inner class),是一段可以传递的代码
基本语法:
<函数式接口> <变量名> = (参数1, 参数2...) -> {
// 方法体
};
箭头操作符(->
)将 Lambda 表达式拆成两部分
左侧:参数列表
右侧:功能,即方法体
注意事项:
- 参数列表的数据类型会自动推断(类型可以省略,JVM编译器可以通过上下文进行类型推断;若类型不确定还是要写的
(String key, User user) -> ...
) - 只有一个参数时,小括号可以省略
- 无参数时,只需保留 ()
- 若只有 1 个参数,() 可省略,只需要参数名称即可
- 若执行语句只有一句,无返回值时,{} 可省略;有返回值时,return 也必须省略
表达式风格 vs 块风格的Lambda
(parameters) -> expression
or
(parameters) -> { statements; }
2.1 扩展:两个箭头
两个箭头,定义两个函数,第一个函数是函数定义函数,第二个是该函数的结果,该函数也恰好是函数
IntFunction<IntUnaryOperator> curriedAdd = (a) -> {
return (b) -> {
return a + b;
};
};
IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
3. 函数式接口(Functional Interface)
- have only one abstract method
函数式接口就是只定义一个抽象方法
的接口(可以有很多默认方法)
函数式接口可以使用 Lambda 表达式,Lambda 表达式会被匹配到这个抽象方法上
@FunctionalInterface
可检测接口是否符合函数式接口
函数式接口的抽象方法的签名基本上就是Lambda表达式的签名。我们将这种抽象方法叫作函数描述符
3.1 常用函数式接口
public interface Consumer<T> {
void accept(T t);
}
public interface Supplier<T> {
T get();
}
public interface Function<T, R> {
R apply(T t);
}
// 谓词(predicate)接受一个参数值,并返回 true 或 false
public interface Predicate<T> {
boolean test(T t);
}
示例:
public static void main(String[] args) {
Consumer<String> consumer = str -> System.out.println(str);
BiConsumer<String, Long> biConsumer = (str, l) -> System.out.println(str + "; " + l);
// demo
consumer.accept("222");
biConsumer.accept("str", 1000L);
Function<Long, String> function = (Long l) -> l.toString();
String apply = function.apply(1000L);
System.out.println(apply);
}
4. Lambda Basics Demo
public void greet(action) { action(); }
- 行为参数化
public class Greeter {
public static void main(String[] args) {
Greeter greeter = new Greeter();
greeter.greet();
}
public void greet() {
System.out.println("Hello World!");
}
}
public interface Greeting {
void perform();
}
public class HelloGreeting implements Greeting {
@Override
public void perform() {
System.out.println("Hello World!");
}
}
public class Greeter {
public static void main(String[] args) {
Greeter greeter = new Greeter();
greeter.greet(new HelloGreeting());
}
// 改进
public void greet(Greeting greeting) {
greeting.perform();
}
}
其他
public class LambdaGrammer {
@Test
public void test1() {
Runnable runnable = () -> System.out.println("running");
// 如果在局部内部类中用了局部变量,在 JDK7 前必须是 final
int num = 0;
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Running..." + num);
// 会报错,本质上还是 final, 默认加上了
// System.out.println("Running..." + num++);
}
};
// Runnable runnable = () -> System.out.println("running" + num);
}
网友评论