文章目录
一、Lambda 表达式
1.1 lambda 语法
lambda
表达式的语法格式如下:
(parameters) -> expression
或
(parameters) ->{ statements; }
以下是lambda
表达式的重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
1.2 lambda 表达式的使用
public class LambdaTest {
public static void main(String[] args) {
LambdaTest tester = new LambdaTest();
//类型声明
MathOperation addition = (int a,int b) ->a+b;
//不声明类型声明
MathOperation subtraction = (a,b)->a-b;
//大括号中的返回语句
MathOperation multiplication = (a,b)->{return a*b;};
//没有大括号及返回语句
MathOperation division = (a,b)->a/b;
System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
System.out.println("10 / 5 = " + tester.operate(10, 5, division));
}
interface MathOperation {
int operation(int a, int b);
}
private int operate(int a, int b, MathOperation mathOperation) {
return mathOperation.operation(a, b);
}
}
Lambda
表达式免去了使用匿名方法的麻烦,很大程度上简化了代码。
public class Test {
public static void main(String[] args) {
//简化前代码
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("TEST");
}
};
//简化后代码
Runnable runnable = () -> System.out.println("TEST");
Thread thread = new Thread(runnable);
thread.start();
}
}
二、函数式接口
Lambda
表达式的类型,也被称为“目标函数”,Lambda
表达式的目标类型必须是“函数式接口(functional interface
)”。函数式接口代表只含有一个抽象方法的接口。Java8专门为函数式接口提供了@FunctionInterface
注解。
Java8
在java.util.function
包下预定义了大量的函数式接口,典型的包含如下4类接口
类型 | 结构 |
---|---|
消费型接口 Consumer | void accept(T t); |
供给型接口 Supplier | T get(); |
函数型接口 Function<T,U> | U apply(T t); |
断定型接口Predicate | boolean test(T t); |
三、方法引用和构造器引用
3.1 方法引用介绍
如果Lambda
表达式的代码块只有一条代码,不仅可以省略花括号,还可以使用方法引用和构造器引用。方法引用通过方法的名字来指向一个方法。方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
要求:
Lambda
体中只有一句,且仅有的一句为方法调用- 实现抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
特例:
- 调用方法的调用者和
Lambda
体实现的抽象方法的第一个参数一致,且其他参数列表完全一样 - 调用方法的返回类型和
Lambda
体实现的抽象方法的返回类型一致
语法:类名::方法名或类名::new
3.2 引用类方法
Function<String,Integer> function = Integer::valueOf;
Integer apply = function.apply("9");
System.out.println(apply);
3.3 引用特定对象的实例方法
Consumer<String> consumer = System.out::println;
consumer.accept("方法引用很好用!");
3.4 引用某类对象的实例方法
public interface Demo {
String test(String a,int b,int c);
}
//主函数方法
Demo demo = String::substring;
String sub = demo.test("abcdef", 1, 2);
System.out.println(sub);
3.5 引用构造器
构造器的参数列表、返回类型正好与抽象方法的参数列表、返回类型一致!
Function<Integer,StringBuffer> function2 = a ->new StringBuffer(a);
--->>>
Function<Integer,StringBuffer> function2 = StringBuffer::new;