例1:
1 public class GroupBy {
2
3 List<Employee> employees = new ArrayList<>();
4
5 /**
6 * 数据初始化
7 */
8 public void init() {
9 List<String> citys = Arrays.asList("湖南", "湖北", "四川", "广东 ");
10 for (int i = 0; i < 10; i++) {
11 Random random = new Random();
12 Integer index = random.nextInt(4);
13 Employee employee = new Employee(citys.get(index), "姓名" + i, (random.nextInt(4) * 10 - random.nextInt(4)),
14 (random.nextInt(4) * 1000 - random.nextInt(4)));
15 employees.add(employee);
16 }
17 }
18
19 /**
20 * 使用java8 stream groupingBy操作,按城市分组list
21 */
22 public void groupingByCity() {
23 Map<String, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity));
24
25 map.forEach((k, v) -> System.out.println(k + " = " + v));
26 //四川 = [GroupBy.Employee(city=四川, name=姓名1, age=30, amount=999), GroupBy.Employee(city=四川, name=姓名2, age=8, amount=2000), GroupBy.Employee(city=四川, name=姓名3, age=30, amount=2997)]
27 //湖南 = [GroupBy.Employee(city=湖南, name=姓名7, age=30, amount=-3), GroupBy.Employee(city=湖南, name=姓名8, age=19, amount=1998)]
28 //湖北 = [GroupBy.Employee(city=湖北, name=姓名4, age=29, amount=-2), GroupBy.Employee(city=湖北, name=姓名5, age=10, amount=1997)]
29 //广东 = [GroupBy.Employee(city=广东 , name=姓名0, age=28, amount=1998), GroupBy.Employee(city=广东 , name=姓名6, age=29, amount=1998), GroupBy.Employee(city=广东 , name=姓名9, age=7, amount=1000)]
30 }
31
32 /**
33 * 使用java8 stream groupingBy操作,按城市分组list统计count
34 */
35 public void groupingByCount() {
36 Map<String, Long> map = employees.stream()
37 .collect(Collectors.groupingBy(Employee::getCity, Collectors.counting()));
38
39 map.forEach((k, v) -> System.out.println(k + " = " + v));
40 //四川 = 1
41 //湖北 = 3
42 //湖南 = 4
43 //广东 = 2
44 }
45
46 /**
47 * 使用java8 stream groupingBy操作,按城市分组list并计算分组年龄平均值
48 */
49 public void groupingByAverage() {
50 Map<String, Double> map = employees.stream()
51 .collect(Collectors.groupingBy(Employee::getCity, Collectors.averagingInt(Employee::getAge)));
52
53 map.forEach((k, v) -> System.out.println(k + " = " + v));
54 //四川 = 15.0
55 //湖北 = 21.25
56 //湖南 = 18.333333333333332
57 //广东 = 9.0
58 }
59
60 /**
61 * 使用java8 stream groupingBy操作,按城市分组list并计算分组销售总值
62 */
63 public void groupingBySum() {
64 Map<String, Long> map = employees.stream()
65 .collect(Collectors.groupingBy(Employee::getCity, Collectors.summingLong(Employee::getAmount)));
66
67 map.forEach((k, v) -> System.out.println(k + " = " + v));
68 //四川 = 3995
69 //湖北 = 2995
70 //湖南 = 999
71 //广东 = 8994
72
73 // 对Map按照分组销售总值逆序排序
74 Map<String, Long> sortedMap = new LinkedHashMap<>();
75 map.entrySet().stream().sorted(Map.Entry.<String, Long> comparingByValue().reversed())
76 .forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue()));
77
78 sortedMap.forEach((k, v) -> System.out.println(k + " = " + v));
79 //广东 = 8994
80 //四川 = 3995
81 //湖北 = 2995
82 //湖南 = 999
83 }
84
85
86 /**
87 * 使用java8 stream groupingBy操作,按城市分组list并通过join操作连接分组list中的对象的name 属性使用逗号分隔
88 */
89 public void groupingByString() {
90 Map<String, String> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity,
91 Collectors.mapping(Employee::getName, Collectors.joining(", ", "Names: [", "]"))));
92
93 map.forEach((k, v) -> System.out.println(k + " = " + v));
94 //四川 = Names: [姓名8]
95 //湖南 = Names: [姓名1, 姓名2, 姓名7]
96 //湖北 = Names: [姓名0, 姓名3, 姓名6, 姓名9]
97 //广东 = Names: [姓名4, 姓名5]
98 }
99
100 /**
101 * 使用java8 stream groupingBy操作,按城市分组list,将List转化为name的List
102 */
103 public void groupingByList() {
104 Map<String, List<String>> map = employees.stream().collect(
105 Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toList())));
106
107 map.forEach((k, v) -> {
108 System.out.println(k + " = " + v);
109 v.forEach(item -> System.out.println("item = " + item));
110 });
111 //四川 = [姓名6]
112 //item = 姓名6
113 //湖北 = [姓名2, 姓名5, 姓名7]
114 //item = 姓名2
115 //item = 姓名5
116 //item = 姓名7
117 //湖南 = [姓名0, 姓名1, 姓名3, 姓名4]
118 //item = 姓名0
119 //item = 姓名1
120 //item = 姓名3
121 //item = 姓名4
122 //广东 = [姓名8, 姓名9]
123 //item = 姓名8
124 //item = 姓名9
125 }
126
127 /**
128 * 使用java8 stream groupingBy操作,按城市分组list,将List转化为name的Set
129 */
130 public void groupingBySet() {
131 Map<String, Set<String>> map = employees.stream().collect(
132 Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toSet())));
133
134 map.forEach((k, v) -> {
135 System.out.println(k + " = " + v);
136 v.forEach(item -> System.out.println("item = " + item));
137 });
138 }
139
140 /**
141 * 使用java8 stream groupingBy操作,通过Object对象的成员分组List
142 */
143 public void groupingByObject() {
144 Map<Manage, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(item -> new Manage(item.getName())));
145
146 map.forEach((k, v) -> System.out.println(k + " = " + v));
147 //GroupBy.Manage(name=姓名9) = [GroupBy.Employee(city=广东 , name=姓名9, age=19, amount=2998)]
148 //GroupBy.Manage(name=姓名8) = [GroupBy.Employee(city=四川, name=姓名8, age=-2, amount=3000)]
149 //GroupBy.Manage(name=姓名7) = [GroupBy.Employee(city=广东 , name=姓名7, age=8, amount=2999)]
150 //GroupBy.Manage(name=姓名2) = [GroupBy.Employee(city=广东 , name=姓名2, age=10, amount=0)]
151 //GroupBy.Manage(name=姓名1) = [GroupBy.Employee(city=四川, name=姓名1, age=-1, amount=1998)]
152 //GroupBy.Manage(name=姓名0) = [GroupBy.Employee(city=湖南, name=姓名0, age=17, amount=1997)]
153 //GroupBy.Manage(name=姓名6) = [GroupBy.Employee(city=湖北, name=姓名6, age=9, amount=1000)]
154 //GroupBy.Manage(name=姓名5) = [GroupBy.Employee(city=湖北, name=姓名5, age=8, amount=1000)]
155 //GroupBy.Manage(name=姓名4) = [GroupBy.Employee(city=湖南, name=姓名4, age=-3, amount=3000)]
156 //GroupBy.Manage(name=姓名3) = [GroupBy.Employee(city=广东 , name=姓名3, age=17, amount=1999)]
157 }
158
159 /**
160 * 使用java8 stream groupingBy操作, 基于city 和name 实现多次分组
161 */
162 public void groupingBys() {
163 Map<String, Map<String, List<Employee>>> map = employees.stream()
164 .collect(Collectors.groupingBy(Employee::getCity, Collectors.groupingBy(Employee::getName)));
165
166 map.forEach((k, v) -> {
167 System.out.println(k + " = " + v);
168 v.forEach((i, j) -> System.out.println(i + " = " + j));
169 });
170 //四川 = {姓名6=[GroupBy.Employee(city=四川, name=姓名6, age=-3, amount=997)]}
171 //姓名6 = [GroupBy.Employee(city=四川, name=姓名6, age=-3, amount=997)]
172
173 //湖南 = {姓名5=[GroupBy.Employee(city=湖南, name=姓名5, age=-2, amount=0)]}
174 //姓名5 = [GroupBy.Employee(city=湖南, name=姓名5, age=-2, amount=0)]
175
176 //湖北 = {姓名4=[GroupBy.Employee(city=湖北, name=姓名4, age=10, amount=-2)], 姓名3=[GroupBy.Employee(city=湖北, name=姓名3, age=8, amount=997)], 姓名2=[GroupBy.Employee(city=湖北, name=姓名2, age=8, amount=999)], 姓名9=[GroupBy.Employee(city=湖北, name=姓名9, age=29, amount=-2)], 姓名1=[GroupBy.Employee(city=湖北, name=姓名1, age=30, amount=2000)]}
177 //姓名4 = [GroupBy.Employee(city=湖北, name=姓名4, age=10, amount=-2)]
178 //姓名3 = [GroupBy.Employee(city=湖北, name=姓名3, age=8, amount=997)]
179 //姓名2 = [GroupBy.Employee(city=湖北, name=姓名2, age=8, amount=999)]
180 //姓名9 = [GroupBy.Employee(city=湖北, name=姓名9, age=29, amount=-2)]
181 //姓名1 = [GroupBy.Employee(city=湖北, name=姓名1, age=30, amount=2000)]
182
183 //广东 = {姓名8=[GroupBy.Employee(city=广东 , name=姓名8, age=-1, amount=-3)], 姓名7=[GroupBy.Employee(city=广东 , name=姓名7, age=29, amount=998)], 姓名0=[GroupBy.Employee(city=广东 , name=姓名0, age=0, amount=2999)]}
184 //姓名8 = [GroupBy.Employee(city=广东 , name=姓名8, age=-1, amount=-3)]
185 //姓名7 = [GroupBy.Employee(city=广东 , name=姓名7, age=29, amount=998)]
186 //姓名0 = [GroupBy.Employee(city=广东 , name=姓名0, age=0, amount=2999)]
187 }
188
189 /**
190 * 使用java8 stream groupingBy操作, 基于Distinct 去重数据
191 */
192 public void groupingByDistinct() {
193 List<Employee> list = employees.stream().filter(distinctByKey(Employee :: getCity))
194 .collect(Collectors.toList());
195
196 list.forEach(item-> System.out.println("city = " + item.getCity()));
197 //city = 湖南
198 //city = 湖北
199 //city = 四川
200 //city = 广东
201 }
202
203 /**
204 * 自定义重复key 规则
205 */
206 private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
207 Set<Object> seen = ConcurrentHashMap.newKeySet();
208 return t -> seen.add(keyExtractor.apply(t));
209 }
210
211 public static void main(String[] args) {
212 GroupBy instance = new GroupBy();
213 instance.init();
214 instance.groupingByCity();
215 instance.groupingByCount();
216 instance.groupingByAverage();
217 instance.groupingBySum();
218 instance.groupingByString();
219 instance.groupingByList();
220 instance.groupingBySet();
221 instance.groupingByObject();
222 instance.groupingBys();
223 instance.groupingByDistinct();
224
225 }
226
227 @Data
228 @NoArgsConstructor
229 @AllArgsConstructor
230 class Employee {
231 private String city;
232 private String name;
233 private Integer age;
234 private Integer amount;
235
236 }
237
238 @Data
239 @NoArgsConstructor
240 @AllArgsConstructor
241 class Manage {
242 private String name;
243
244 }
245
246 }
例2:
1 /**
2 * 分组List并显示其总数
3 */
4 @Test
5 void test1(){
6 //3 apple, 2 banana, others 1
7 List items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya");
8 Map<String, Long> collect = items.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
9 System.out.println(collect); //{papaya=1, orange=1, banana=2, apple=3}
10 }
11
12 /**
13 * 添加排序
14 */
15 @Test
16 void test2(){
17 List<String> items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya");
18 Map<String, Long> map = items.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
19 Map<String, Long> finalMap = new LinkedHashMap<>();
20 map.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed()).forEachOrdered(e->finalMap.put(e.getKey(),e.getValue()));
21
22 System.out.println(finalMap); //{apple=3, banana=2, papaya=1, orange=1}
23 }
24
25 /**
26 * 按姓名+ 数字或数量组合
27 */
28 @Test
29 void test3(){
30 //3 apple, 2 banana, others 1
31 List<Item> items = Arrays.asList(
32 new Item("apple", 10, new BigDecimal("9.99")),
33 new Item("banana", 20, new BigDecimal("19.99")),
34 new Item("orange", 10, new BigDecimal("29.99")),
35 new Item("watermelon", 10, new BigDecimal("29.99")),
36 new Item("papaya", 20, new BigDecimal("9.99")),
37 new Item("apple", 10, new BigDecimal("9.99")),
38 new Item("banana", 10, new BigDecimal("19.99")),
39 new Item("apple", 20, new BigDecimal("9.99"))
40 );
41 Map<String, Long> counting = items.stream().collect(Collectors.groupingBy(Item::getName, Collectors.counting()));
42 System.out.println(counting); //{papaya=1, orange=1, banana=2, apple=3, watermelon=1}
43
44 Map<String, Integer> map = items.stream().collect(Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getNumber)));
45 System.out.println(map); //{papaya=20, orange=10, banana=30, apple=40, watermelon=10}
46 }
47
48 /**
49 * 按价格分组
50 */
51 @Test
52 void test4(){
53 //3 apple, 2 banana, others 1
54 List<Item> items = Arrays.asList(
55 new Item("apple", 10, new BigDecimal("9.99")),
56 new Item("banana", 20, new BigDecimal("19.99")),
57 new Item("orange", 10, new BigDecimal("29.99")),
58 new Item("watermelon", 10, new BigDecimal("29.99")),
59 new Item("papaya", 20, new BigDecimal("9.99")),
60 new Item("apple", 10, new BigDecimal("9.99")),
61 new Item("banana", 10, new BigDecimal("19.99")),
62 new Item("apple", 20, new BigDecimal("9.99"))
63 );
64 Map<BigDecimal, List<Item>> decimalListMap = items.stream().collect(Collectors.groupingBy(Item::getPrice));
65 System.out.println(decimalListMap);
66 //{19.99=[Item(name=banana, number=20, price=19.99),
67 // Item(name=banana, number=10, price=19.99)],
68 // 29.99=[Item(name=orange, number=10, price=29.99),
69 // Item(name=watermelon, number=10, price=29.99)],
70 // 9.99=[Item(name=apple, number=10, price=9.99),
71 // Item(name=papaya, number=20, price=9.99),
72 // Item(name=apple, number=10, price=9.99),
73 // Item(name=apple, number=20, price=9.99)]}
74
75 Map<BigDecimal, Set<String>> setMap = items.stream().collect(Collectors.groupingBy(Item::getPrice, Collectors.mapping(Item::getName, Collectors.toSet())));
76 System.out.println(setMap);
77 //{19.99=[banana],
78 // 29.99=[orange, watermelon],
79 // 9.99=[papaya, apple]}
80 }