Optional
Java 8 引入的特性是 Optional 类。Optional 类主要解决的问题是空指针异常(NullPointerException)。
本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。
public static void main(String[] args) {
Map<String, Object> map = null;
forEach(map);
}
public static void forEach(Map<String, Object> map) {
Optional<Map<String,Object>> map = Optional.ofNullable(map);
map.ifPresent(consumer -> {
consumer.forEach((k, v) -> {
System.out.println("key = " + k);
System.out.println("value = " + v);
});
});
}
Stream
stream 是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
注意:
Stream 自己不会存储元素。
Stream 不改变源对象。相反,它们回返回一个持有结果的新 Stream。
Stream 操作时延迟进行的。这意味着它们会等到需要结果的时候才执行。
List<A>
=>List<B>
public class FileDTO {
private String name;
private Long lastModified;
private Long size;
public FileDTO(File file) {
this.name = file.getName();
this.lastModified = file.lastModified();
this.size = file.length();
}
}
Arrays.stream(files).map(file -> new FileDTO(file)).collect(Collectors.toList());
// List<Integer> => List<String>
List<String> stringList = intList.stream().map(String::valueOf).collect(Collectors.toList());
- 分隔字符串
idList.stream().map(String::valueOf).collect(Collectors.joining(","));
Lambda 表达式
通用
Lambda 匿名类
- 单个参数,可缺省括号
Consumer<String> consumer = x -> {
System.out.println(x);
}
consumer.accept("Hello World!");
- 只有一条语句,可缺省花括号
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("Hello World!");
- 有返回值,且只有一条语句,return 语句可省略
Comparator<Integer> comparator = (x, y) -> {
return Integer.compare(x, y);
}
comparator.compare(6, 3);
Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
comparator.compare(6, 3);
四大核心函数式接口
- Consumer 消费型接口
传入参数,进行消费,如:List.forEach(Consumer)
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
- Supplier 供给型接口
@FunctionalInterface
public interface Supplier<T> {
T get();
}
- Predicate 断言型接口
传入需要考察的变量,返回布尔值。而且,函数模型未必使用 Predicate
,因为它只支持 1 个参数,可以根据需求进行自定义,如:FilenameFilter
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
- Function 函数型接口
更加通用的一种。传入对象,返回对象。甚至使用 andThen()
可以进行管道操作。
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
<V> Function<T, V> andThen(Function<? super R, ? extends V> after);
}
方法引用
当参数列表和返回值都相同,可以使用方法引用,一种函数式接口的缩写:
Comparator<Integer> comparator1 = Integer::compare;
// 等价于
Comparator<Integer> comparator2 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
};
MyBatisPlus 比较常用的 LambdaWrapper 需要传入 SFunction,因此可以常见一些缩写 User::getUsername
等。