Java 8 Lambda表达式,常用接口,Stream流式处理

Lambda 表达式 — Oracle 官方文档 — Lambda Expressions (The Java™ Tutorials > Learning the Java Language > Classes and Objects) 2022-07-16 18:00:29
Lambda 表达式 方法引用 — Oracle 官方文档 — Method References (The Java™ Tutorials > Learning the Java Language > Classes and Objects) 2022-07-16 18:05:41

Lambda

Lambda表达式

函数式接口

1
2
3
4
5
6
7
函数式接口:有且只有一个抽象方法的接口,称之为函数式接口
当然接口中可以包含其他的方法(默认,静态,私有)

`@FunctionalInterface`注解
作用:定义在接口上,可以检测接口是否是一个函数式接口
是:编译成功
否:编译失败(接口中没有抽象方法抽象方法的个数多余1个)

基本语法

()->{}

1
2
3
4
5
6
7
8
1. `()`参数,参数声明可以省略
数量=0,必须写成`()`
数量=1,可写成`(x)`,也可省略小括号直接写成`x`
数量>1,必须加上括号,例如两个参数可写成`(x,y)`
2. `->`传递,表示参数传递给方法体,不可省略
3. `{}`重写的方法体
无返回值,必须加上大括号`{}`,如果只有一行执行语句可省略大括号
有返回值,可直接写成`()->2`等同于`()->{return 2;}`

在这里插入图片描述

日志优化案例

在这里插入图片描述

使用场景

作为方法参数

在这里插入图片描述

作为方法返回值

在这里插入图片描述

对象名引用成员方法

在这里插入图片描述

类名引用静态方法

在这里插入图片描述

super引用父类方法

在这里插入图片描述

this引用本类方法

在这里插入图片描述

类构造器引用

在这里插入图片描述

数组构造器引用

在这里插入图片描述

常用接口

Supplier

提供者

1
2
3
4
5
@FunctionalInterface
public interface Supplier<T> {

T get();
}

在这里插入图片描述

Consumer

消费者

1
2
3
4
5
6
7
8
9
10
@FunctionalInterface
public interface Consumer<T> {

void accept(T t);

default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}

在这里插入图片描述

Predicate

布尔值函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@FunctionalInterface
public interface Predicate<T> {

boolean test(T t);

default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}

default Predicate<T> negate() {
return (t) -> !test(t);
}

default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}

static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}

在这里插入图片描述

Function

类型转换函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@FunctionalInterface
public interface Function<T, R> {

R apply(T t);

default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}

static <T> Function<T, T> identity() {
return t -> t;
}
}

在这里插入图片描述

Stream

Stream流式处理

思想

流式思想
所以流只能被消费一次。再次使用会有异常。请见异常案例
在这里插入图片描述

获取

获取Stream流

1
2
3
4
5
6
7
java.util.stream.Stream<T>是Java 8新加入的最常用的流接口。(这并不是一个函数式接口。)
获取一个流非常简单,有以下几种常用的方式:
- 所有的Collection集合都可以通过stream默认方法获取流;
default Stream<E> stream​()
- Stream接口的静态方法of可以获取数组对应的流。
static <T> Stream<T> of​(T... values)
参数是一个可变参数,那么我们就可以传递一个数组

在这里插入图片描述

forEach

循环
在这里插入图片描述

filter

过滤
在这里插入图片描述

map

映射
在这里插入图片描述

flatMap

将流展开(看下面例子:将一个 list 中的 subList 进行合并)

2021-11-12 16:00:52 补充

1
2
3
4
5
6
7
8
9
10
11
12
13
List<List<Integer>> list = new ArrayList<>();
list.add(new ArrayList<>(Arrays.asList(11, 12, 13)));
list.add(new ArrayList<>(Arrays.asList(14, 15, 16)));

List<Integer> list2 = list.stream().flatMap(e -> e.stream()).collect(Collectors.toList());
String s2 = list2.toString();
// 将两个子数组合并成一个数组
// [11, 12, 13, 14, 15, 16]

List<Integer> list3 = list.stream().flatMap(e -> e.stream().map(ee -> ee * 2)).collect(Collectors.toList());
String s3 = list3.toString();
// 将两个子数组合并成一个数组,并元素扩大2倍
// [22, 24, 26, 28, 30, 32]

count

统计
在这里插入图片描述

limit

限制
在这里插入图片描述

skip

跳过
在这里插入图片描述

concat

合并
在这里插入图片描述

distinct

去重
在这里插入图片描述

max

最大值
在这里插入图片描述

min

最小值
在这里插入图片描述

average

平均值
在这里插入图片描述

sum

求和
在这里插入图片描述

reduce

归约
2021-11-06 00:56:40

1
2
3
4
5
6
7
8
List<BigDecimal> list = new ArrayList<>(Arrays.asList(1.1, 2.2, 3.3)).stream().map(BigDecimal::valueOf).collect(Collectors.toList());

// 1、指定泛型
BigDecimal reduce = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);// 6.6

// 2、不指定
Optional<BigDecimal> optional = list.stream().reduce(BigDecimal::add);
BigDecimal reduce2 = optional.get();// 6.6

sorted

排序
在这里插入图片描述

2021-11-12 16:50:45

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
List<Integer> list = Arrays.asList(22, 11, 33);


// 集合 sort,stream.sorted 都传比较器
// Comparator<Integer> c = Comparator.naturalOrder();
// list.sort(c);
// list = list.stream().sorted(c).collect(Collectors.toList());

// ASC
list.sort(Comparator.naturalOrder());// [11, 22, 33]
list = list.stream().sorted().collect(Collectors.toList());
list = list.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
list = list.stream().sorted(Comparator.comparing(e -> e)).collect(Collectors.toList());
list = list.stream().sorted(Comparator.comparingInt(e -> e)).collect(Collectors.toList());
list = list.stream().sorted(Integer::compare).collect(Collectors.toList());

// DESC
list.sort(Comparator.reverseOrder());// [33, 22, 11]
list = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

// [{"order":1},{"order":2},{"order":3}]
String json = "[{\"order\":3},{\"order\":1},{\"order\":2}]";
List<Map> list2 = JSONUtil.toList(json, Map.class);

// ASC
// Comparator.comparingInt(e -> Integer.parseInt(e.get("order").toString()))
list2.sort(Comparator.comparingInt(e -> Integer.parseInt(e.get("order").toString())));// [{order=1}, {order=2}, {order=3}]
list2 = list2.stream().sorted(Comparator.comparingInt(e -> Integer.parseInt(e.get("order").toString()))).collect(Collectors.toList());

// DESC
// Comparator.comparing(e -> Integer.parseInt(e.get("order").toString()), Comparator.reverseOrder())
list2.sort(Comparator.comparing(e -> Integer.parseInt(e.get("order").toString()), Comparator.reverseOrder()));// [{order=3}, {order=2}, {order=1}]
list2 = list2.stream().sorted(Comparator.comparing(e -> Integer.parseInt(e.get("order").toString()), Comparator.reverseOrder())).collect(Collectors.toList());

toList

collect转List
在这里插入图片描述

collect

收集

2021-11-12 17:31:43

1
2
3
4
5
6
7
8
9
10
11
List<String> list = Arrays.asList("b", "c", "a");

List<String> collect = list.stream().collect(Collectors.toList());

Set<String> collect1 = list.stream().collect(Collectors.toSet());

TreeSet<String> collect2 = list.stream().collect(Collectors.toCollection(TreeSet::new));

String collect3 = list.stream().collect(Collectors.joining());// "bca"
String collect4 = list.stream().collect(Collectors.joining(","));// "b,c,a"
String collect5 = list.stream().collect(Collectors.joining(",","[","]"));// "[b,c,a]"

toMap

collect转Map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class Person
{

private Integer id;

private String name;

private String sex;

private Integer age;

省略构造/set/get/toString
}

List<Person> personList = Arrays.asList(
new Person(1, "大牛", "男", 11),
new Person(2, "二蛋", "女", 22),
new Person(3, "三驴", "男", 33),
new Person(4, "四毛", "男", 55),
new Person(5, "五虎", "女", 55),
new Person(6, "六豹牛", "男", 55));


/*Id,对应对象*/
Map<Integer, Person> collect3 = personList.stream().collect(Collectors.toMap(Person::getId, p -> p));
System.out.println(collect3);
/*
{1=Person{id=1, name='大牛', sex='男', age=11},
2=Person{id=2, name='二蛋', sex='女', age=22},
3=Person{id=3, name='三驴', sex='男', age=33},
4=Person{id=4, name='四毛', sex='男', age=55},
5=Person{id=5, name='五虎', sex='女', age=55},
6=Person{id=6, name='六豹牛', sex='男', age=55}}
*/

/*Id,对应名字*/
Map<Integer, String> collect4 = personList.stream().collect(Collectors.toMap(Person::getId, Person::getName));
System.out.println(collect4);
/*
{1=大牛, 2=二蛋, 3=三驴, 4=四毛, 5=五虎, 6=六豹牛}
*/

/*年龄,对应姓名
* (k1, k2) -> k1) 姓名不覆盖
* (k1, k2) -> k2) 姓名覆盖
* */
Map<Integer, String> collect6 = personList.stream().collect(Collectors.toMap(Person::getAge, Person::getName, (k1, k2) -> k1));
System.out.println(collect6);
/*
{33=三驴, 22=二蛋, 55=四毛, 11=大牛}
*/


//案例:把data_init的转为 Map<String, String>
Map<String, Object> data_init = (Map<String, Object>) entry.getValue();
Map<String, String> data = data_init.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, node -> node.getValue().toString()));

groupingBy

分组

1
2
3
4
5
6
7
8
9
/*按照年龄分组*/
Map<Integer, List<Person>> collect5 = personList.stream().collect(Collectors.groupingBy(Person::getAge));
System.out.println(collect5);
/*
{33=[Person{id=3, name='三驴', sex='男', age=33}],
22=[Person{id=2, name='二蛋', sex='女', age=22}],
55=[Person{id=4, name='四毛', sex='男', age=55}, Person{id=5, name='五虎', sex='女', age=55}, Person{id=6, name='六豹牛', sex='男', age=55}],
11=[Person{id=1, name='大牛', sex='男', age=11}]}
*/