1
1
package com .bobocode .fp ;
2
2
3
+ import com .bobocode .fp .exception .EntityNotFoundException ;
3
4
import com .bobocode .model .Account ;
4
5
import com .bobocode .util .ExerciseNotCompletedException ;
5
6
import lombok .AllArgsConstructor ;
6
7
7
8
import java .math .BigDecimal ;
8
9
import java .time .Month ;
9
10
import java .util .*;
11
+ import java .util .stream .Collectors ;
12
+ import java .util .stream .Stream ;
10
13
11
14
/**
12
15
* {@link CrazyStreams} is an exercise class. Each method represent some operation with a collection of accounts that
@@ -30,7 +33,8 @@ public class CrazyStreams {
30
33
* @return account with max balance wrapped with optional
31
34
*/
32
35
public Optional <Account > findRichestPerson () {
33
- throw new ExerciseNotCompletedException ();
36
+ return accounts .stream ()
37
+ .max (Comparator .comparing (Account ::getBalance ));
34
38
}
35
39
36
40
/**
@@ -40,7 +44,10 @@ public Optional<Account> findRichestPerson() {
40
44
* @return a list of accounts
41
45
*/
42
46
public List <Account > findAccountsByBirthdayMonth (Month birthdayMonth ) {
43
- throw new ExerciseNotCompletedException ();
47
+ return accounts .stream ()
48
+ .filter (account -> account .getBirthday ()
49
+ .getMonth ().equals (birthdayMonth ))
50
+ .toList ();
44
51
}
45
52
46
53
/**
@@ -50,7 +57,9 @@ public List<Account> findAccountsByBirthdayMonth(Month birthdayMonth) {
50
57
* @return a map where key is true or false, and value is list of male, and female accounts
51
58
*/
52
59
public Map <Boolean , List <Account >> partitionMaleAccounts () {
53
- throw new ExerciseNotCompletedException ();
60
+ return accounts .stream ()
61
+ .collect (Collectors .partitioningBy (
62
+ account -> "MALE" .equalsIgnoreCase (account .getSex ().toString ())));
54
63
}
55
64
56
65
/**
@@ -60,7 +69,9 @@ public Map<Boolean, List<Account>> partitionMaleAccounts() {
60
69
* @return a map where key is an email domain and value is a list of all account with such email
61
70
*/
62
71
public Map <String , List <Account >> groupAccountsByEmailDomain () {
63
- throw new ExerciseNotCompletedException ();
72
+ return accounts .stream ()
73
+ .collect (Collectors .groupingBy (
74
+ account -> account .getEmail ().split ("@" )[1 ]));
64
75
}
65
76
66
77
/**
@@ -69,7 +80,10 @@ public Map<String, List<Account>> groupAccountsByEmailDomain() {
69
80
* @return total number of letters of first and last names of all accounts
70
81
*/
71
82
public int getNumOfLettersInFirstAndLastNames () {
72
- throw new ExerciseNotCompletedException ();
83
+ return accounts .stream ()
84
+ .mapToInt (account -> account .getFirstName ().length ()
85
+ + account .getLastName ().length ())
86
+ .sum ();
73
87
}
74
88
75
89
/**
@@ -78,7 +92,9 @@ public int getNumOfLettersInFirstAndLastNames() {
78
92
* @return total balance of all accounts
79
93
*/
80
94
public BigDecimal calculateTotalBalance () {
81
- throw new ExerciseNotCompletedException ();
95
+ return BigDecimal .valueOf (accounts .stream ()
96
+ .mapToInt (account -> account .getBalance ().intValue ())
97
+ .sum ());
82
98
}
83
99
84
100
/**
@@ -87,7 +103,10 @@ public BigDecimal calculateTotalBalance() {
87
103
* @return list of accounts sorted by first and last names
88
104
*/
89
105
public List <Account > sortByFirstAndLastNames () {
90
- throw new ExerciseNotCompletedException ();
106
+ return accounts .stream ()
107
+ .sorted (Comparator .comparing (Account ::getFirstName )
108
+ .thenComparing (Account ::getLastName ))
109
+ .toList ();
91
110
}
92
111
93
112
/**
@@ -97,7 +116,8 @@ public List<Account> sortByFirstAndLastNames() {
97
116
* @return true if there is an account that has an email with provided domain
98
117
*/
99
118
public boolean containsAccountWithEmailDomain (String emailDomain ) {
100
- throw new ExerciseNotCompletedException ();
119
+ return accounts .stream ()
120
+ .anyMatch (account -> account .getEmail ().split ("@" )[1 ].equals (emailDomain ));
101
121
}
102
122
103
123
/**
@@ -108,7 +128,12 @@ public boolean containsAccountWithEmailDomain(String emailDomain) {
108
128
* @return account balance
109
129
*/
110
130
public BigDecimal getBalanceByEmail (String email ) {
111
- throw new ExerciseNotCompletedException ();
131
+ return accounts .stream ()
132
+ .filter (account -> account .getEmail ().equals (email ))
133
+ .map (Account ::getBalance )
134
+ .findFirst ()
135
+ .orElseThrow (() -> new EntityNotFoundException (
136
+ "Cannot find Account by email=" + email ));
112
137
}
113
138
114
139
/**
@@ -117,7 +142,8 @@ public BigDecimal getBalanceByEmail(String email) {
117
142
* @return map of accounts by its ids
118
143
*/
119
144
public Map <Long , Account > collectAccountsById () {
120
- throw new ExerciseNotCompletedException ();
145
+ return accounts .stream ()
146
+ .collect (Collectors .toMap (Account ::getId , account -> account ));
121
147
}
122
148
123
149
/**
@@ -128,7 +154,9 @@ public Map<Long, Account> collectAccountsById() {
128
154
* @return map of account by its ids the were created in a particular year
129
155
*/
130
156
public Map <String , BigDecimal > collectBalancesByEmailForAccountsCreatedOn (int year ) {
131
- throw new ExerciseNotCompletedException ();
157
+ return accounts .stream ()
158
+ .filter (account -> account .getCreationDate ().getYear () == year )
159
+ .collect (Collectors .toMap (Account ::getEmail , Account ::getBalance ));
132
160
}
133
161
134
162
/**
@@ -138,7 +166,10 @@ public Map<String, BigDecimal> collectBalancesByEmailForAccountsCreatedOn(int ye
138
166
* @return a map where key is a last name and value is a set of first names
139
167
*/
140
168
public Map <String , Set <String >> groupFirstNamesByLastNames () {
141
- throw new ExerciseNotCompletedException ();
169
+ return accounts .stream ()
170
+ .collect (Collectors .groupingBy (
171
+ Account ::getLastName , Collectors .mapping (
172
+ Account ::getFirstName , Collectors .toSet ())));
142
173
}
143
174
144
175
/**
@@ -148,7 +179,11 @@ public Map<String, Set<String>> groupFirstNamesByLastNames() {
148
179
* @return a map where a key is a birthday month and value is comma-separated first names
149
180
*/
150
181
public Map <Month , String > groupCommaSeparatedFirstNamesByBirthdayMonth () {
151
- throw new ExerciseNotCompletedException ();
182
+
183
+ return accounts .stream ()
184
+ .collect (Collectors .groupingBy (
185
+ account -> account .getBirthday ().getMonth (),
186
+ Collectors .mapping (Account ::getFirstName , Collectors .joining (", " ))));
152
187
}
153
188
154
189
/**
@@ -158,7 +193,9 @@ public Map<Month, String> groupCommaSeparatedFirstNamesByBirthdayMonth() {
158
193
* @return a map where key is a creation month and value is total balance of all accounts created in that month
159
194
*/
160
195
public Map <Month , BigDecimal > groupTotalBalanceByCreationMonth () {
161
- throw new ExerciseNotCompletedException ();
196
+ return accounts .stream ().collect (Collectors .groupingBy (
197
+ account -> account .getCreationDate ().getMonth (),
198
+ Collectors .reducing (BigDecimal .ZERO , Account ::getBalance , BigDecimal ::add )));
162
199
}
163
200
164
201
/**
@@ -168,7 +205,9 @@ public Map<Month, BigDecimal> groupTotalBalanceByCreationMonth() {
168
205
* @return a map where key is a letter and value is its count in all first names
169
206
*/
170
207
public Map <Character , Long > getCharacterFrequencyInFirstNames () {
171
- throw new ExerciseNotCompletedException ();
208
+ return accounts .stream ()
209
+ .flatMap (account -> account .getFirstName ().chars ().mapToObj (c -> (char ) c ))
210
+ .collect (Collectors .groupingBy (c -> c , Collectors .counting ()));
172
211
}
173
212
174
213
/**
@@ -179,7 +218,11 @@ public Map<Character, Long> getCharacterFrequencyInFirstNames() {
179
218
* @return a map where key is a letter and value is its count ignoring case in all first and last names
180
219
*/
181
220
public Map <Character , Long > getCharacterFrequencyIgnoreCaseInFirstAndLastNames (int nameLengthBound ) {
182
- throw new ExerciseNotCompletedException ();
221
+ return accounts .stream ()
222
+ .flatMap (account -> Stream .of (account .getFirstName (), account .getLastName ()))
223
+ .filter (name -> name != null && name .length () >= nameLengthBound )
224
+ .flatMap (name -> name .toLowerCase ().chars ().mapToObj (c -> (char ) c ))
225
+ .collect (Collectors .groupingBy (c -> c , Collectors .counting ()));
183
226
}
184
227
185
228
}
0 commit comments