Skip to content

Commit f4e6c16

Browse files
committed
Java Stream操作总结
1 parent 9f18fe8 commit f4e6c16

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Java Stream常见用法汇总,开发效率大幅提升
2+
3+
Java8 新增的 Stream 流大大减轻了我们代码的工作量,但是 Stream 流的用法较多,实际使用的时候容易遗忘,整理一下供大家参考。
4+
5+
## 1. 概述
6+
7+
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来对 Java 集合运算和表达的高阶抽象。
8+
9+
Stream API 可以极大提高 Java 程序员的生产力,让程序员写出高效率、干净、简洁的代码。
10+
11+
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
12+
13+
![](http://img.topjavaer.cn/img/stream1.png)
14+
15+
## 2. 创建
16+
17+
### 2.1 集合自带 Stream 流方法
18+
19+
```
20+
List<String> list = new ArrayList<>();
21+
// 创建一个顺序流
22+
Stream<String> stream = list.stream();
23+
// 创建一个并行流
24+
Stream<String> parallelStream = list.parallelStream();
25+
```
26+
27+
### 2.1 通过 Array 数组创建
28+
29+
```
30+
int[] array = {1,2,3,4,5};
31+
IntStream stream = Arrays.stream(array);
32+
```
33+
34+
### 2.3 使用 Stream 的静态方法创建
35+
36+
```
37+
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
38+
Stream<Integer> stream = Stream.iterate(0, (x) -> x + 3).limit(3); // 输出 0,3,6
39+
40+
Stream<String> stream = Stream.generate(() -> "Hello").limit(3); // 输出 Hello,Hello,Hello
41+
Stream<Double> stream = Stream.generate(Math::random).limit(3); // 输出3个随机数
42+
```
43+
44+
### 2.3 数值流
45+
46+
```
47+
// 生成有限的常量流
48+
IntStream intStream = IntStream.range(1, 3); // 输出 1,2
49+
IntStream intStream = IntStream.rangeClosed(1, 3); // 输出 1,2,3
50+
// 生成一个等差数列
51+
IntStream.iterate(1, i -> i + 3).limit(5).forEach(System.out::println); // 输出 1,4,7,10,13
52+
// 生成无限常量数据流
53+
IntStream generate = IntStream.generate(() -> 10).limit(3); // 输出 10,10,10
54+
```
55+
56+
另外还有 LongStream、DoubleStream 都有这几个方法。
57+
58+
## 3. 使用
59+
60+
初始化一些数据,示例中使用。
61+
62+
```
63+
public class Demo {
64+
class User{
65+
// 姓名
66+
private String name;
67+
68+
// 年龄
69+
private Integer age;
70+
}
71+
72+
public static void main(String[] args) {
73+
List<User> users = new ArrayList<>();
74+
users.add(new User("Tom", 1));
75+
users.add(new User("Jerry", 2));
76+
}
77+
}
78+
```
79+
80+
### 3.1 遍历 forEach
81+
82+
```
83+
// 循环输出user对象
84+
users.stream().forEach(user -> System.out.println(user));
85+
```
86+
87+
### 3.2 查找 find
88+
89+
```
90+
// 取出第一个对象
91+
User user = users.stream().findFirst().orElse(null); // 输出 {"age":1,"name":"Tom"}
92+
// 随机取出任意一个对象
93+
User user = users.stream().findAny().orElse(null);
94+
```
95+
96+
### 3.3 匹配 match
97+
98+
```
99+
// 判断是否存在name是Tom的用户
100+
boolean existTom = users.stream().anyMatch(user -> "Tom".equals(user.getName()));
101+
// 判断所有用户的年龄是否都小于5
102+
boolean checkAge = users.stream().allMatch(user -> user.getAge() < 5);
103+
```
104+
105+
### 3.4 筛选 filter
106+
107+
```
108+
// 筛选name是Tom的用户
109+
users.stream()
110+
.filter(user -> "Tom".equals(user.name))
111+
.forEach(System.out::println); // 输出 {"age":1,"name":"Tom"}
112+
```
113+
114+
### 3.5 映射 map/flatMap
115+
116+
```
117+
// 打印users里的name
118+
users.stream().map(User::getName).forEach(System.out::println); // 输出 Tom Jerry
119+
// List<List<User>> 转 List<User>
120+
List<List<User>> userList = new ArrayList<>();
121+
List<User> users = userList.stream().flatMap(Collection::stream).collect(Collectors.toList());
122+
```
123+
124+
### 3.6 归约 reduce
125+
126+
```
127+
// 求用户年龄之和
128+
Integer sum = users.stream().map(User::getAge).reduce(Integer::sum).orElse(0);
129+
// 求用户年龄的乘积
130+
Integer product = users.stream().map(User::getAge).reduce((x, y) -> x * y).orElse(0);
131+
```
132+
133+
### 3.7 排序 sorted
134+
135+
```
136+
// 按年龄倒序排
137+
List<User> collect = users.stream()
138+
.sorted(Comparator.comparing(User::getAge).reversed())
139+
.collect(Collectors.toList());
140+
141+
//多属性排序
142+
List<Person> result = persons.stream()
143+
.sorted(Comparator.comparing((Person p) -> p.getNamePinyin())
144+
.thenComparing(Person::getAge)).collect(Collectors.toList());
145+
```
146+
147+
### 3.8 收集 collect
148+
149+
```
150+
// list转换成map
151+
Map<Integer, User> map = users.stream()
152+
.collect(Collectors.toMap(User::getAge, Function.identity()));
153+
154+
// 按年龄分组
155+
Map<Integer, List<User>> userMap = users.stream().collect(Collectors.groupingBy(User::getAge));
156+
157+
// 求平均年龄
158+
Double ageAvg = users.stream().collect(Collectors.averagingInt(User::getAge)); // 输出 1.5
159+
160+
// 求年龄之和
161+
Integer ageSum = users.stream().collect(Collectors.summingInt(User::getAge));
162+
163+
// 求年龄最大的用户
164+
User user = users.stream().collect(Collectors.maxBy(Comparator.comparing(User::getAge))).orElse(null);
165+
166+
// 把用户姓名拼接成逗号分隔的字符串输出
167+
String names = users.stream().map(User::getName).collect(Collectors.joining(",")); // 输出 Tom,Jerry
168+
```
169+
170+
### 3.9 List 转换成 Map 时遇到重复主键
171+
172+
![](http://img.topjavaer.cn/img/stream2.png)
173+
174+
这样转换会报错,因为 ID 重复。
175+
176+
![](http://img.topjavaer.cn/img/stream3.png)
177+
178+
可以这样做
179+
180+
![](http://img.topjavaer.cn/img/stream4.png)
181+
182+
183+
184+
--end--

0 commit comments

Comments
 (0)