Java8技术系列:Lambda
Java8技术系列:Java8提供的函数式接口和集合流
函数式接口
函数式接口(Functional Interfaces):如果一个接口定义了唯一的一个方法,那么这个接口就是函数式接口。
同时,引入了注解 @FunctionalInterface
,可以使用它注解接口表示是函数式接口。这个注解是非必需的,只要接口只包含一个方法,虚拟机会自动判断为函数式接口,不过最好在接口上使用注解 @FunctionalInterface
声明。
lambda表达式
lambda是java8引入的一个语法,lambda表达式可以让代码更加简洁,lambda表达式方法体是函数式接口的方法实现,lambda实例化函数式接口。
即是用了lambda表达式,可以省略了接口的实现,如下:
// 传统写法
Interface interface = new Interface() {
@Override
public Model test() {
return new Model();
}
};
// lambda写法
// 省略了new Interface(){}直接操作方法体内的实现
Interface interface = Model::new;
主要优点:
-
代码变得更加简洁紧凑
-
可读性强
-
并行操作大集合变得很方便,可以充分发挥多核CPU的优势,更加便于多核处理器编写代码等
lambda语法
lambda参数和表达式
语法结构:
parameters -> expression
语法说明:
-
->:lambda表达式操作符
-
**parameters:**指定lambda表达式需要的所有参数
-
**expression:**指定lambda表达式要执行的任务、功能或行为
parameters展示类型:
-
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值
-
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号
expression展示类型:
-
可选的大括号:如果主体只有一个表达式语句,不需要使用
{}
括起来 -
可选的返回关键字return:如果主体只有一个表达式,返回值可以省略
return
和{}
example
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 1、lambda左侧参数语法说明:
// 只有一个参数x,可以不定义参数类型String,编译器会统一识别参数值类型
Arrays.asList("a", "b", "c").forEach((String x) -> System.out.println(x));
Arrays.asList("a", "b", "c").forEach(x -> System.out.println(x));
// 只有一个参数x,可以不需要定义圆括号囊括参数
Arrays.asList("a", "b", "c").forEach((x) -> System.out.println(x));
Arrays.asList("a", "b", "c").forEach(x -> System.out.println(x));
// 有两个参数x和y,需要定义圆括号囊括参数
Arrays.asList("a", "b", "c").stream().sorted((x, y) -> y.compareTo(x)).forEach(x -> System.out.println(x));
// 函数式接口没有参数,可以直接使用圆括号代替
new Thread(() -> System.out.println("lambda non parameters")).start();
// 2、lambda右侧表达式语法说明:
// 函数只有一个表达式,不需要return关键字和{ }囊括即可返回数值
Arrays.asList("a", "b", "c").stream().sorted((x, y) -> y.compareTo(x)).forEach(x -> System.out.println(x));
// 函数有多条表达式语句,需要使用{ }囊括起来且有返回值需要使用return关键字返回
Arrays.asList("a", "b", "c").stream().sorted((x, y) -> {
System.out.println("lambda has more than one parameter and method has more element");
return y.compareTo(x);
}).forEach(x -> System.out.println(x));
}
}
lambda方法引用
语法结构:
ObjectRef :: methodName
语法说明:
-
:::lambda方法引用操作符
-
**ObjectRef:**指定类名或实例名
-
**methodName:**指定调用的类或实例方法
方法引用一般分为三类:
-
静态方法引用
-
实例方法引用
-
构造方法引用
example
@FunctionalInterface
public interface Transform<A, B> {
B transform(A a);
}
public class LambdaData {
public LambdaData() {
}
public LambdaData(String s) {
}
public static int strToInt(String str) {
return Integer.valueOf(str);
}
public String intToStr(int value) {
return String.valueOf(value);
}
}
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 1、静态方法引用
// 传统写法
Transform<String, Integer> transform = new Transform<String, Integer>() {
@Override
public Integer transform(String s) {
return LambdaData.strToInt(s);
}
};
// lambda写法
Transform<String, Integer> transform = LambdaData :: strToInt;
// 2、实例方法引用
// 传统写法
Transform<Integer, String> transform = new Transform<Integer, String>() {
@Override
public String transform(Integer integer) {
return new LambdaData().intToStr(integer);
}
};
// lambda写法
Transform<Integer, String> transform = new LambdaData() :: intToStr;
// 3、构造方法引用
Transform<String, LambdaData> transform = new Transform<String, LambdaData>() {
@Override
public LambdaData transform(String s) {
return new LambdaData(s);
}
};
// lambda写法
Transform<String, LambdaData> transform = LambdaData::new;
}
}