老鬼的博客 来都来啦,那就随便看看吧~
stream常用方法
发布于: 2022-06-09 更新于: 2022-06-09 分类于:  阅读次数: 

一:介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
定义:流是 Java API 的新成员,它允许以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。
就现在来说,可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,也就是说不用写多线程代码了。

Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。
原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给
出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream
会隐式地在内部进行遍历,做出相应的数据转换。

Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水
从面前流过,一去不复返。而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。
顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多
个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的
Fork/Join 框架(JSR166y)来拆分任务和加速处理过程。

二:快速创建List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Stream使用of执行初始化,然后再转成list
List<Integer> list1 = Stream.of(1, 2, 3, 4).collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(list1)));

// Stream使用of执行初始化,然后再转成map对象,其中toMap第一个是key,第二个是value
Map<String, String> map1 = Stream.of("A", "B", "C", "D").collect(Collectors.toMap(n -> n + "_k", n -> n));

System.out.println(map1.toString());
// list转成Stream
List<Apple> list2 = Arrays.asList(new Apple(1, "red", 500, "湖南"), new Apple(2, "red", 100, "天津"),
new Apple(3, "green", 300, "湖南"));
List<Apple> list3 = list2.stream().filter(p -> p.getWeight() > 200).collect(Collectors.toList());
List<Integer> list4 = list3.stream().map(Apple::getId).collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(list2)));
System.out.println(JSONArray.parseArray(JSON.toJSONString(list3)));
System.out.println(JSONArray.parseArray(JSON.toJSONString(list4)));

二:stream的常用操作

2.1 快速创建list

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
// 一.快速创建list

// 1.1 new一个list,一个一个添加
Apple apple1 = new Apple(1, "red", 500, "湖南");
Apple apple2 = new Apple(2, "red", 100, "南京");
Apple apple3 = new Apple(3, "green", 300, "南京");
Apple apple4 = new Apple(4, "green", 200, "广州");
Apple apple5 = new Apple(5, "green", 100, "北京");
Apple apple6 = new Apple(6, "blue", 50, "上海");
List<Apple> list = new ArrayList<>();
list.add(apple1);
list.add(apple2);
list.add(apple3);
list.add(apple4);
list.add(apple5);

// 1.2 Stream流:创建动态list,可以添加元素
list = Stream.of(apple1, apple2, apple3, apple4, apple5).collect(Collectors.toList());
list.add(apple6);
System.out.println(JSONArray.parseArray(JSON.toJSONString(list)));

// 1.3 如果创建一个固定长度的list,可以使用Arrays.asList(…args)直接返回一个list
// 本质是将一个数组转成list,数组的大小是固定的,所以此list不能添加元素,
// 如果调用add方法增加新的元素,会报异常:java.lang.UnsupportedOperationException
// 当元素是固定时,可以采用这个;
list = Arrays.asList(apple1, apple2, apple3, apple4, apple5);
// list.add(apple6);//这里会报 java.lang.UnsupportedOperationException
System.out.println(JSONArray.parseArray(JSON.toJSONString(list)));

2.2 取对象的某一列

2.2.1 遍历
1
2
3
4
5
6
7
8
List<String> newList = new ArrayList<>();
// if判断
for (Apple apple : list) {
if (apple.getBirthplace().equalsIgnoreCase("南京")) {
newList.add(apple.getBirthplace());
}
}
System.out.println(JSONArray.parseArray(JSON.toJSONString(newList)));
2.2.2 使用Stream map
1
2
3
newList = list.stream().filter(apple -> apple.getBirthplace().equalsIgnoreCase("南京")).map(Apple::getBirthplace)
.collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(newList)));

2.3 过滤,或者说是根据一个判断条件筛选出目标对象

2.3.1 遍历加 if
1
2
3
4
5
6
7
List<Apple> newAppleList = new ArrayList<>();
for (Apple apple : list) {
if (apple.getWeight() > 200) {
newAppleList.add(apple);
}
}
System.out.println(JSONArray.parseArray(JSON.toJSONString(newAppleList)));
2.3.2 使用Stream filter
1
2
newAppleList = list.stream().filter(apple -> apple.getWeight() > 200).collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(newAppleList)));

2.4 分组

2.4.1 遍历+if
1
2
3
4
5
6
7
8
Map<String, List<Apple>> map = new HashMap<>();
for (Apple apple : list) {
if (map.get(apple.getBirthplace()) == null) {
map.put(apple.getBirthplace(), new ArrayList<Apple>());
}
map.get(apple.getBirthplace()).add(apple);
}
System.out.println(JSONObject.parseObject(JSON.toJSONString(map)).toString());
2.4.2 Stream流:groupingBy
1
2
map = list.stream().collect(Collectors.groupingBy(Apple::getBirthplace, Collectors.toList()));
System.out.println(JSONObject.parseObject(JSON.toJSONString(map)).toString());

2.5 stream求和

1
2
Integer sum = list.stream().mapToInt(Apple::getWeight).sum();
System.out.println(sum);

2.6 list转map

2.6.1 循环
1
2
3
4
5
6
7
Map<String, Apple> appleMap = new HashMap<>();
for (Apple apple : list) {
appleMap.put(apple.getBirthplace(), apple);
}
// 这里会有其他问题出现,如果map的key不唯一,那么后面会被覆盖掉
System.out.println(JSONArray.parseArray(JSON.toJSONString(list)));
System.out.println(JSONObject.parseObject(JSON.toJSONString(appleMap)).toString());
2.6.2 stream toMap
1
2
3
4
用Collectors的toMap方法转换List,一般会遇到两个问题。 (1)转换map,key重复问题;
代码中使用(key1,key2)->key2表达式可以解决此类问题,如果出现重复的key就使用key2覆盖前面的key1,
也可以定义成(key1,key2)->key1,保留key1,根据自己的业务场景来调整。
空指针异常,即转为map的value是null。这个可以用filter过滤;
1
2
3
appleMap = list.stream()
.collect(Collectors.toMap(Apple::getBirthplace, Function.identity(), (key1, key2) -> key1));
System.out.println(JSONObject.parseObject(JSON.toJSONString(appleMap)).toString());

2.7 map转list

2.7.1 遍历
1
2
3
4
List<Apple> list2 = new ArrayList<Apple>();
for (String birthplace : appleMap.keySet()) {
list2.add(appleMap.get(birthplace));
}
2.7.2 stream流
1
2
list2 = appleMap.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(list2)));

三:总结

1
2
流作为jdk1.8新成员,简化了我们之前对list或者map的一些操作,本来需要遍历才能解决的问题,
现在可以使用stream的filter,map,collect等操作来完成

四:完整代码

4.1 Apple.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.tohours.wechatapi.test.jdk8;

import lombok.Data;

@Data
public class Apple {
private int id; // 编号
private String color; // 颜色
private int weight; // 重量
private String birthplace; // 产地

public Apple(int id, String color, int weight, String birthplace) {
this.id = id;
this.color = color;
this.weight = weight;
this.birthplace = birthplace;
}

}

4.2 StreamTest.java

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package com.tohours.wechatapi.test.jdk8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
* @desc jdk1.8 Stream API
* @author RenJie
* @date 2022-06-07
*
*/
public class StreamTest {


/**
* @desc Stream的一些初始化
*/
public static void test() {
// Stream使用of执行初始化,然后再转成list
List<Integer> list1 = Stream.of(1, 2, 3, 4).collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(list1)));
// Stream使用of执行初始化,然后再转成map对象,其中toMap第一个是key,第二个是value
Map<String, String> map1 = Stream.of("A", "B", "C", "D").collect(Collectors.toMap(n -> n + "_k", n -> n));
System.out.println(map1.toString());
// list转成Stream
List<Apple> list2 = Arrays.asList(new Apple(1, "red", 500, "湖南"), new Apple(2, "red", 100, "天津"),
new Apple(3, "green", 300, "湖南"));
List<Apple> list3 = list2.stream().filter(p -> p.getWeight() > 200).collect(Collectors.toList());
List<Integer> list4 = list3.stream().map(Apple::getId).collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(list2)));
System.out.println(JSONArray.parseArray(JSON.toJSONString(list3)));
System.out.println(JSONArray.parseArray(JSON.toJSONString(list4)));
}

/**
* @desc stream常用方法
*/
public static void test1() {

// 一.快速创建list

// 1.1 new一个list,一个一个添加
Apple apple1 = new Apple(1, "red", 500, "湖南");
Apple apple2 = new Apple(2, "red", 100, "南京");
Apple apple3 = new Apple(3, "green", 300, "南京");
Apple apple4 = new Apple(4, "green", 200, "广州");
Apple apple5 = new Apple(5, "green", 100, "北京");
Apple apple6 = new Apple(6, "blue", 50, "上海");
List<Apple> list = new ArrayList<>();
list.add(apple1);
list.add(apple2);
list.add(apple3);
list.add(apple4);
list.add(apple5);
// 1.2 Stream流:创建动态list,可以添加元素
list = Stream.of(apple1, apple2, apple3, apple4, apple5).collect(Collectors.toList());
list.add(apple6);
System.out.println(JSONArray.parseArray(JSON.toJSONString(list)));
// 1.3 如果创建一个固定长度的list,可以使用Arrays.asList(…args)直接返回一个list
// 本质是将一个数组转成list,数组的大小是固定的,所以此list不能添加元素,
// 如果调用add方法增加新的元素,会报异常:java.lang.UnsupportedOperationException
// 当元素是固定时,可以采用这个;
list = Arrays.asList(apple1, apple2, apple3, apple4, apple5);
// list.add(apple6);//这里会报 java.lang.UnsupportedOperationException
System.out.println(JSONArray.parseArray(JSON.toJSONString(list)));

// 二:取对象的某一列:
// 2.1 遍历
List<String> newList = new ArrayList<>();
// if判断
for (Apple apple : list) {
if (apple.getBirthplace().equalsIgnoreCase("南京")) {
newList.add(apple.getBirthplace());
}
}
System.out.println(JSONArray.parseArray(JSON.toJSONString(newList)));

// 2.2 使用Stream map
newList = list.stream().filter(apple -> apple.getBirthplace().equalsIgnoreCase("南京")).map(Apple::getBirthplace)
.collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(newList)));

// 三: 过滤,或者说是根据一个判断条件筛选出目标对象
// 3.1 遍历加 if
List<Apple> newAppleList = new ArrayList<>();
for (Apple apple : list) {
if (apple.getWeight() > 200) {
newAppleList.add(apple);
}
}
System.out.println(JSONArray.parseArray(JSON.toJSONString(newAppleList)));

// 3.2 使用Stream filter
newAppleList = list.stream().filter(apple -> apple.getWeight() > 200).collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(newAppleList)));

// 四:分组
Map<String, List<Apple>> map = new HashMap<>();
// 4.1 循环 if判断
for (Apple apple : list) {
if (map.get(apple.getBirthplace()) == null) {
map.put(apple.getBirthplace(), new ArrayList<Apple>());
}
map.get(apple.getBirthplace()).add(apple);
}
System.out.println(JSONObject.parseObject(JSON.toJSONString(map)).toString());
// 4.2 Stream流:groupingBy
map = list.stream().collect(Collectors.groupingBy(Apple::getBirthplace, Collectors.toList()));
System.out.println(JSONObject.parseObject(JSON.toJSONString(map)).toString());

// 五:求和,stream求和
// int、double、long:
Integer sum = list.stream().mapToInt(Apple::getWeight).sum();
System.out.println(sum);

// 六:Map、List互转
// 6.1 list转map:
Map<String, Apple> appleMap = new HashMap<>();
for (Apple apple : list) {
appleMap.put(apple.getBirthplace(), apple);
}
// 这里会有其他问题出现,如果map的key不唯一,那么后面会被覆盖掉
System.out.println(JSONArray.parseArray(JSON.toJSONString(list)));
System.out.println(JSONObject.parseObject(JSON.toJSONString(appleMap)).toString());

/***
* 用Collectors的toMap方法转换List,一般会遇到两个问题。 (1)转换map,key重复问题;
* 代码中使用(key1,key2)->key2表达式可以解决此类问题,如果出现重复的key就使用key2覆盖前面的key1,也可以定义成(key1,key2)->key1,保留key1,根据自己的业务场景来调整。
* (2)空指针异常,即转为map的value是null。这个可以用filter过滤;
*/

appleMap = list.stream()
.collect(Collectors.toMap(Apple::getBirthplace, Function.identity(), (key1, key2) -> key1));
System.out.println(JSONObject.parseObject(JSON.toJSONString(appleMap)).toString());

// 6.2 map转list

// 6.2.1 遍历
List<Apple> list2 = new ArrayList<Apple>();
for (String birthplace : appleMap.keySet()) {
list2.add(appleMap.get(birthplace));
}
System.out.println(JSONArray.parseArray(JSON.toJSONString(list2)));
// 6.2.2 stream流
list2 = appleMap.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toList());
System.out.println(JSONArray.parseArray(JSON.toJSONString(list2)));

}

public static void main(String[] args) {
test();
test1();
}

}
*************感谢您的阅读*************