diff --git a/5-0-functional-programming/5-2-1-crazy-streams/src/main/java/com/bobocode/fp/CrazyStreams.java b/5-0-functional-programming/5-2-1-crazy-streams/src/main/java/com/bobocode/fp/CrazyStreams.java index 40ffc170f..8ad0e6fa5 100644 --- a/5-0-functional-programming/5-2-1-crazy-streams/src/main/java/com/bobocode/fp/CrazyStreams.java +++ b/5-0-functional-programming/5-2-1-crazy-streams/src/main/java/com/bobocode/fp/CrazyStreams.java @@ -1,12 +1,18 @@ package com.bobocode.fp; +import com.bobocode.data.Accounts; +import com.bobocode.fp.exception.EntityNotFoundException; import com.bobocode.model.Account; +import com.bobocode.model.Sex; import com.bobocode.util.ExerciseNotCompletedException; import lombok.AllArgsConstructor; import java.math.BigDecimal; import java.time.Month; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; /** * {@link CrazyStreams} is an exercise class. Each method represent some operation with a collection of accounts that @@ -30,7 +36,7 @@ public class CrazyStreams { * @return account with max balance wrapped with optional */ public Optional findRichestPerson() { - throw new ExerciseNotCompletedException(); + return accounts.stream().max(Comparator.comparing(Account::getBalance)); } /** @@ -40,7 +46,7 @@ public Optional findRichestPerson() { * @return a list of accounts */ public List findAccountsByBirthdayMonth(Month birthdayMonth) { - throw new ExerciseNotCompletedException(); + return accounts.stream().filter(i -> i.getBirthday().getMonth().equals(birthdayMonth)).collect(Collectors.toList()); } /** @@ -50,7 +56,7 @@ public List findAccountsByBirthdayMonth(Month birthdayMonth) { * @return a map where key is true or false, and value is list of male, and female accounts */ public Map> partitionMaleAccounts() { - throw new ExerciseNotCompletedException(); + return accounts.stream().collect(Collectors.groupingBy(i -> i.getSex().equals(Sex.MALE))); } /** @@ -60,7 +66,7 @@ public Map> partitionMaleAccounts() { * @return a map where key is an email domain and value is a list of all account with such email */ public Map> groupAccountsByEmailDomain() { - throw new ExerciseNotCompletedException(); + return accounts.stream().collect(Collectors.groupingBy(i -> i.getEmail().substring(i.getEmail().indexOf("@") + 1))); } /** @@ -69,7 +75,7 @@ public Map> groupAccountsByEmailDomain() { * @return total number of letters of first and last names of all accounts */ public int getNumOfLettersInFirstAndLastNames() { - throw new ExerciseNotCompletedException(); + return accounts.stream().mapToInt(i -> i.getFirstName().length() + i.getLastName().length()).sum(); } /** @@ -78,7 +84,7 @@ public int getNumOfLettersInFirstAndLastNames() { * @return total balance of all accounts */ public BigDecimal calculateTotalBalance() { - throw new ExerciseNotCompletedException(); + return accounts.stream().map(Account::getBalance).reduce(BigDecimal::add).get(); } /** @@ -87,7 +93,7 @@ public BigDecimal calculateTotalBalance() { * @return list of accounts sorted by first and last names */ public List sortByFirstAndLastNames() { - throw new ExerciseNotCompletedException(); + return accounts.stream().sorted(Comparator.comparing(Account::getFirstName).thenComparing(Account::getLastName)).collect(Collectors.toList()); } /** @@ -97,7 +103,7 @@ public List sortByFirstAndLastNames() { * @return true if there is an account that has an email with provided domain */ public boolean containsAccountWithEmailDomain(String emailDomain) { - throw new ExerciseNotCompletedException(); + return groupAccountsByEmailDomain().containsKey(emailDomain); } /** @@ -108,7 +114,7 @@ public boolean containsAccountWithEmailDomain(String emailDomain) { * @return account balance */ public BigDecimal getBalanceByEmail(String email) { - throw new ExerciseNotCompletedException(); + return accounts.stream().filter(i -> i.getEmail().equals(email)).map(Account::getBalance).findFirst().orElseThrow(() -> new EntityNotFoundException("Cannot find Account by email=" + email)); } /** @@ -117,7 +123,7 @@ public BigDecimal getBalanceByEmail(String email) { * @return map of accounts by its ids */ public Map collectAccountsById() { - throw new ExerciseNotCompletedException(); + return accounts.stream().collect(Collectors.toMap(Account::getId, i -> i)); } /** @@ -128,7 +134,7 @@ public Map collectAccountsById() { * @return map of account by its ids the were created in a particular year */ public Map collectBalancesByEmailForAccountsCreatedOn(int year) { - throw new ExerciseNotCompletedException(); + return accounts.stream().filter(i -> i.getCreationDate().getYear() == year).collect(Collectors.toMap(Account::getEmail, Account::getBalance)); } /** @@ -138,7 +144,7 @@ public Map collectBalancesByEmailForAccountsCreatedOn(int ye * @return a map where key is a last name and value is a set of first names */ public Map> groupFirstNamesByLastNames() { - throw new ExerciseNotCompletedException(); + return accounts.stream().collect(Collectors.groupingBy(Account::getLastName, Collectors.mapping(Account::getFirstName, Collectors.toSet()))); } /** @@ -148,7 +154,7 @@ public Map> groupFirstNamesByLastNames() { * @return a map where a key is a birthday month and value is comma-separated first names */ public Map groupCommaSeparatedFirstNamesByBirthdayMonth() { - throw new ExerciseNotCompletedException(); + return accounts.stream().collect(Collectors.groupingBy(i -> i.getBirthday().getMonth(), Collectors.mapping(Account::getFirstName, Collectors.joining(", ")))); } /** @@ -158,7 +164,11 @@ public Map groupCommaSeparatedFirstNamesByBirthdayMonth() { * @return a map where key is a creation month and value is total balance of all accounts created in that month */ public Map groupTotalBalanceByCreationMonth() { - throw new ExerciseNotCompletedException(); + return accounts.stream().collect(Collectors.groupingBy(i -> i.getCreationDate().getMonth(), Collectors.reducing( + BigDecimal.ZERO, + Account::getBalance, + BigDecimal::add + ))); } /** @@ -168,9 +178,19 @@ public Map groupTotalBalanceByCreationMonth() { * @return a map where key is a letter and value is its count in all first names */ public Map getCharacterFrequencyInFirstNames() { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .map(Account::getFirstName) + .flatMapToInt(String::chars) // символы из строк + .mapToObj(c -> (char) c) // превращаем в Character + .filter(Character::isLetter) // оставляем только буквы + .collect(Collectors.toMap( + ch -> ch, + ch -> 1L, + Long::sum + )); } + /** * Returns a {@link Map} where key is a letter {@link Character}, and value is a number of its occurrences ignoring * case, in all {@link Account#firstName} and {@link Account#lastName} that are equal or longer than nameLengthBound. @@ -179,8 +199,19 @@ public Map getCharacterFrequencyInFirstNames() { * @return a map where key is a letter and value is its count ignoring case in all first and last names */ public Map getCharacterFrequencyIgnoreCaseInFirstAndLastNames(int nameLengthBound) { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .flatMap(acc -> Stream.of( + acc.getFirstName().length() >= nameLengthBound ? acc.getFirstName().toLowerCase() : "", + acc.getLastName().length() >= nameLengthBound ? acc.getLastName().toLowerCase() : "" + )) + .flatMapToInt(String::chars) + .mapToObj(c -> (char) c) + .filter(Character::isLetter) + .collect(Collectors.toMap( + ch -> ch, + ch -> 1L, + Long::sum + )); } - }