1
+ package com .ak .app ;
2
+
3
+ import org .junit .jupiter .api .Test ;
4
+
5
+ import java .util .*;
6
+ import java .util .concurrent .ConcurrentHashMap ;
7
+ import java .util .concurrent .ConcurrentMap ;
8
+ import java .util .function .BiConsumer ;
9
+ import java .util .function .Consumer ;
10
+ import java .util .function .Function ;
11
+ import java .util .stream .Collectors ;
12
+ import java .util .stream .Stream ;
13
+
14
+ import static org .assertj .core .api .Assertions .assertThat ;
15
+ import static org .assertj .core .api .Assertions .entry ;
16
+
17
+ class CollectionsAndCollectorsTest {
18
+ record Employee (String firstName , String lastName , String position , int salary ) {
19
+ }
20
+
21
+ private final List <Employee > employees = List .of (
22
+ new Employee ("AAA" , "BBB" , "developer" , 10_000 ),
23
+ new Employee ("AAB" , "BBC" , "architect" , 15_000 ),
24
+ new Employee ("AAC" , "BBD" , "developer" , 13_000 ),
25
+ new Employee ("AAD" , "BBE" , "tester" , 7_000 ),
26
+ new Employee ("AAE" , "BBF" , "tester" , 9_000 )
27
+ );
28
+
29
+ /**
30
+ * <a href='https://piotrminkowski.com/2024/04/25/interesting-facts-about-java-streams-and-collections/'>
31
+ * Interesting Facts About Java Streams and Collections
32
+ * </a>
33
+ */
34
+ @ Test
35
+ void groupingAndAggregations () {
36
+ var m = employees .stream ().collect (
37
+ Collectors .groupingBy (
38
+ Employee ::position ,
39
+ Collectors .summingInt (Employee ::salary )
40
+ )
41
+ );
42
+
43
+ assertThat (m ).hasSize (3 )
44
+ .contains (entry ("developer" , 23000 ))
45
+ .contains (entry ("architect" , 15000 ))
46
+ .contains (entry ("tester" , 16000 ));
47
+
48
+ var p = employees .stream ().collect (Collectors .partitioningBy (e -> e .salary > 10_000 ));
49
+ assertThat (p ).hasSize (2 )
50
+ .hasEntrySatisfying (Boolean .TRUE , es -> assertThat (es ).hasSize (2 ))
51
+ .hasEntrySatisfying (Boolean .FALSE , es -> assertThat (es ).hasSize (3 ));
52
+ }
53
+
54
+ /**
55
+ * <p>
56
+ * <a href="https://stackabuse.com/guide-to-java-8-collectors-groupingbyconcurrent/">Guide to Java 8 Collectors: groupingByConcurrent()</a>
57
+ * </p>
58
+ *
59
+ * <p>
60
+ * <a href="https://habr.com/ru/articles/684912//">Практические примеры использования Stream API</a>
61
+ * </p>
62
+ */
63
+ @ Test
64
+ void groupingByConcurrent () {
65
+ record Book (String title , String author , int releaseYear ) {
66
+ }
67
+
68
+ String georgeOrwell = "George Orwell" ;
69
+ String tolkien = "J.R.R. Tolkien" ;
70
+ String williamGolding = "William Golding" ;
71
+ List <Book > books = Arrays .asList (
72
+ new Book ("The Lord of the Rings" , tolkien , 1954 ),
73
+ new Book ("The Hobbit" , tolkien , 1937 ),
74
+ new Book ("Animal Farm" , georgeOrwell , 1945 ),
75
+ new Book ("Nineteen Eighty-Four" , georgeOrwell , 1949 ),
76
+ new Book ("The Road to Wigan Pier" , georgeOrwell , 1937 ),
77
+ new Book ("Lord of the Flies" , williamGolding , 1954 )
78
+ );
79
+
80
+ ConcurrentMap <String , List <String >> booksByAuthor = books .parallelStream ()
81
+ .collect (
82
+ Collectors .groupingByConcurrent (Book ::author , ConcurrentHashMap ::new , Collectors .mapping (Book ::title , Collectors .toList ()))
83
+ );
84
+ assertThat (booksByAuthor )
85
+ .hasEntrySatisfying (georgeOrwell , strings -> assertThat (strings ).hasSize (3 ))
86
+ .hasEntrySatisfying (tolkien , strings -> assertThat (strings ).hasSize (2 ))
87
+ .hasEntrySatisfying (williamGolding , strings -> assertThat (strings ).hasSize (1 ));
88
+ }
89
+
90
+ /**
91
+ * <a href="https://stackoverflow.com/questions/19031213/java-get-most-common-element-in-a-list">Java-get most common element in a list</a>
92
+ */
93
+ @ Test
94
+ void mostCommonElement () {
95
+ var v = Stream .of (1 , 3 , 4 , 3 , 2 , 3 , 3 , 3 , 3 , 4 )
96
+ .collect (Collectors .groupingBy (Function .identity (), Collectors .counting ()))
97
+ .entrySet ().stream ().max (Map .Entry .comparingByValue ()).orElseThrow ();
98
+ assertThat (v .getKey ()).isEqualTo (3 );
99
+ assertThat (v .getValue ()).isEqualTo (6 );
100
+ }
101
+
102
+ @ Test
103
+ void maxElementKey () {
104
+ var map = Map .of ("1" , 1 , "2" , 2 , "3" , 3 );
105
+ String maxKey = Collections .max (map .entrySet (), Map .Entry .comparingByValue ()).getKey ();
106
+ assertThat (maxKey ).isEqualTo ("3" );
107
+ }
108
+
109
+ /**
110
+ * <a href="https://blogs.oracle.com/javamagazine/post/the-hidden-gems-in-java-16-and-java-17-from-streammapmulti-to-hexformat">Hidden gems in Java 16 and Java 17, from Stream.mapMulti to HexFormat</a>
111
+ */
112
+ @ Test
113
+ void mapMulti () {
114
+ List <String > strings = Stream .of ("Java" , "Valhalla" , "Panama" , "Loom" , "Amber" )
115
+ .mapMulti ((BiConsumer <String , Consumer <String >>) (s , mapper ) -> {
116
+ if (s .length () >= 5 ) {
117
+ mapper .accept (s );
118
+ }
119
+ })
120
+ .toList ();
121
+ assertThat (strings ).containsExactly ("Valhalla" , "Panama" , "Amber" );
122
+ }
123
+
124
+ /**
125
+ * <a href='https://piotrminkowski.com/2024/04/25/interesting-facts-about-java-streams-and-collections/'>
126
+ * Interesting Facts About Java Streams and Collections
127
+ * </a>
128
+ */
129
+ @ Test
130
+ void mapMerge () {
131
+ var map = new HashMap <Integer , Integer >();
132
+ var nums = List .of (2 , 3 , 4 , 2 , 3 , 5 , 1 , 3 , 4 , 4 );
133
+ nums .forEach (num -> map .merge (num , 1 , Integer ::sum ));
134
+ assertThat (map ).hasSize (5 ).contains (entry (4 , 3 ));
135
+ }
136
+
137
+ @ Test
138
+ void mapMerge2 () {
139
+ var map = new HashMap <String , Integer >();
140
+ employees .forEach (emp -> map .merge (emp .position (), emp .salary (), Integer ::sum ));
141
+ assertThat (map ).hasSize (3 ).contains (entry ("developer" , 23000 ));
142
+ }
143
+ }
0 commit comments