-
Notifications
You must be signed in to change notification settings - Fork 710
/
StreamDetailTest.java
266 lines (222 loc) · 11.5 KB
/
StreamDetailTest.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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
package javaprogramming.commonmistakes.java8;
import javaprogramming.commonmistakes.java8.collector.MostPopularCollector;
import org.junit.Before;
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.BinaryOperator;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.Comparator.comparing;
import static java.util.Comparator.comparingDouble;
import static java.util.stream.Collectors.*;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public class StreamDetailTest {
private static Random random = new Random();
private List<Order> orders;
@Before
public void data() {
orders = Order.getData();
orders.forEach(System.out::println);
System.out.println("==========================================");
}
@Test
public void filter() {
System.out.println("//最近半年的金额大于40的订单");
orders.stream()
.filter(Objects::nonNull)
.filter(order -> order.getPlacedAt().isAfter(LocalDateTime.now().minusMonths(6)))
.filter(order -> order.getTotalPrice() > 40)
.forEach(System.out::println);
}
@Test
public void map() {
//计算所有订单商品数量
//通过两次遍历实现
LongAdder longAdder = new LongAdder();
orders.stream().forEach(order ->
order.getOrderItemList().forEach(orderItem -> longAdder.add(orderItem.getProductQuantity())));
//使用两次mapToLong+sum方法实现
assertThat(longAdder.longValue(), is(orders.stream().mapToLong(order ->
order.getOrderItemList().stream()
.mapToLong(OrderItem::getProductQuantity).sum()).sum()));
//把IntStream通过转换Stream<Project>
System.out.println(IntStream.rangeClosed(1, 10)
.mapToObj(i -> new Product((long) i, "product" + i, i * 100.0))
.collect(toList()));
}
@Test
public void sorted() {
System.out.println("//大于50的订单,按照订单价格倒序前5");
orders.stream().filter(order -> order.getTotalPrice() > 50)
.sorted(comparing(Order::getTotalPrice).reversed())
.limit(5)
.forEach(System.out::println);
}
@Test
public void flatMap() {
//不依赖订单上的总价格字段
System.out.println(orders.stream().mapToDouble(order -> order.getTotalPrice()).sum());
//如果不依赖订单上的总价格,可以直接展开订单商品进行价格统计
System.out.println(orders.stream()
.flatMap(order -> order.getOrderItemList().stream())
.mapToDouble(item -> item.getProductQuantity() * item.getProductPrice()).sum());
//另一种方式flatMap+mapToDouble=flatMapToDouble
System.out.println(orders.stream()
.flatMapToDouble(order ->
order.getOrderItemList()
.stream().mapToDouble(item -> item.getProductQuantity() * item.getProductPrice()))
.sum());
}
@Test
public void groupBy() {
System.out.println("//按照用户名分组,统计下单数量");
System.out.println(orders.stream().collect(groupingBy(Order::getCustomerName, counting()))
.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed()).collect(toList()));
System.out.println("//按照用户名分组,统计订单总金额");
System.out.println(orders.stream().collect(groupingBy(Order::getCustomerName, summingDouble(Order::getTotalPrice)))
.entrySet().stream().sorted(Map.Entry.<String, Double>comparingByValue().reversed()).collect(toList()));
System.out.println("//按照用户名分组,统计商品采购数量");
System.out.println(orders.stream().collect(groupingBy(Order::getCustomerName,
summingInt(order -> order.getOrderItemList().stream()
.collect(summingInt(OrderItem::getProductQuantity)))))
.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).collect(toList()));
System.out.println("//统计最受欢迎的商品,倒序后取第一个");
orders.stream()
.flatMap(order -> order.getOrderItemList().stream())
.collect(groupingBy(OrderItem::getProductName, summingInt(OrderItem::getProductQuantity)))
.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.map(Map.Entry::getKey)
.findFirst()
.ifPresent(System.out::println);
System.out.println("//统计最受欢迎的商品的另一种方式,直接利用maxBy");
orders.stream()
.flatMap(order -> order.getOrderItemList().stream())
.collect(groupingBy(OrderItem::getProductName, summingInt(OrderItem::getProductQuantity)))
.entrySet().stream()
.collect(maxBy(Map.Entry.comparingByValue()))
.map(Map.Entry::getKey)
.ifPresent(System.out::println);
System.out.println("//按照用户名分组,选用户下的总金额最大的订单");
orders.stream().collect(groupingBy(Order::getCustomerName, collectingAndThen(maxBy(comparingDouble(Order::getTotalPrice)), Optional::get)))
.forEach((k, v) -> System.out.println(k + "#" + v.getTotalPrice() + "@" + v.getPlacedAt()));
System.out.println("//根据下单年月分组统计订单ID列表");
System.out.println(orders.stream().collect
(groupingBy(order -> order.getPlacedAt().format(DateTimeFormatter.ofPattern("yyyyMM")),
mapping(order -> order.getId(), toList()))));
System.out.println("//根据下单年月+用户名两次分组,统计订单ID列表");
System.out.println(orders.stream().collect
(groupingBy(order -> order.getPlacedAt().format(DateTimeFormatter.ofPattern("yyyyMM")),
groupingBy(order -> order.getCustomerName(),
mapping(order -> order.getId(), toList())))));
}
@Test
public void maxMin() {
orders.stream().max(comparing(Order::getTotalPrice)).ifPresent(System.out::println);
orders.stream().min(comparing(Order::getTotalPrice)).ifPresent(System.out::println);
}
@Test
public void reduce() {
System.out.println("//统计花钱最多的人");
System.out.println(orders.stream().collect(groupingBy(Order::getCustomerName, summingDouble(Order::getTotalPrice)))
.entrySet().stream()
.reduce(BinaryOperator.maxBy(Map.Entry.comparingByValue()))
.map(Map.Entry::getKey).orElse("N/A"));
}
@Test
public void distinct() {
System.out.println("//不去重的下单用户");
System.out.println(orders.stream().map(order -> order.getCustomerName()).collect(joining(",")));
System.out.println("//去重的下单用户");
System.out.println(orders.stream().map(order -> order.getCustomerName()).distinct().collect(joining(",")));
System.out.println("//所有购买过的商品");
System.out.println(orders.stream()
.flatMap(order -> order.getOrderItemList().stream())
.map(OrderItem::getProductName)
.distinct().collect(joining(",")));
}
@Test
public void collect() {
System.out.println("//生成一定位数的随机字符串");
System.out.println(random.ints(48, 122)
.filter(i -> (i < 57 || i > 65) && (i < 90 || i > 97))
.mapToObj(i -> (char) i)
.limit(20)
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString());
System.out.println("//所有下单的用户,使用toSet去重了");
System.out.println(orders.stream()
.map(order -> order.getCustomerName()).collect(toSet())
.stream().collect(joining(",", "[", "]")));
System.out.println("//用toCollection收集器指定集合类型");
System.out.println(orders.stream().limit(2).collect(toCollection(LinkedList::new)).getClass());
System.out.println("//使用toMap获取订单ID+下单用户名的Map");
orders.stream()
.collect(toMap(Order::getId, Order::getCustomerName))
.entrySet().forEach(System.out::println);
System.out.println("//使用toMap获取下单用户名+最近一次下单时间的Map");
orders.stream()
.collect(toMap(Order::getCustomerName, Order::getPlacedAt, (x, y) -> x.isAfter(y) ? x : y))
.entrySet().forEach(System.out::println);
System.out.println("//订单平均购买的商品数量");
System.out.println(orders.stream().collect(averagingInt(order ->
order.getOrderItemList().stream()
.collect(summingInt(OrderItem::getProductQuantity)))));
}
@Test
public void partition() {
//先来看一下所有下单的用户
orders.stream().map(order -> order.getCustomerName()).collect(toSet()).forEach(System.out::println);
//根据是否有下单记录进行分区
System.out.println(Customer.getData().stream().collect(
partitioningBy(customer -> orders.stream().mapToLong(Order::getCustomerId)
.anyMatch(id -> id == customer.getId()))));
}
@Test
public void skipLimit() {
orders.stream()
.sorted(comparing(Order::getPlacedAt))
.map(order -> order.getCustomerName() + "@" + order.getPlacedAt())
.limit(2).forEach(System.out::println);
orders.stream()
.sorted(comparing(Order::getPlacedAt))
.map(order -> order.getCustomerName() + "@" + order.getPlacedAt())
.skip(2).limit(2).forEach(System.out::println);
}
@Test
public void peek() {
IntStream.rangeClosed(1, 10)
.peek(i -> {
System.out.println("第一次peek");
System.out.println(i);
})
.filter(i -> i > 5)
.peek(i -> {
System.out.println("第二次peek");
System.out.println(i);
})
.filter(i -> i % 2 == 0)
.forEach(i -> {
System.out.println("最终结果");
System.out.println(i);
});
// orders.stream()
// .filter(order -> order.getTotalPrice() > 40)
// .peek(order -> System.out.println(order.toString()))
// .map(Order::getCustomerName)
// .collect(toList());
}
@Test
public void customCollector() //自定义收集器
{
//最受欢迎收集器
assertThat(Stream.of(1, 1, 2, 2, 2, 3, 4, 5, 5).collect(new MostPopularCollector<>()).get(), is(2));
assertThat(Stream.of('a', 'b', 'c', 'c', 'c', 'd').collect(new MostPopularCollector<>()).get(), is('c'));
assertThat(Stream.concat(Stream.concat(IntStream.rangeClosed(1, 1000).boxed(), IntStream.rangeClosed(1, 1000).boxed()), Stream.of(2))
.parallel().collect(new MostPopularCollector<>()).get(), is(2));
}
}