├── .gitignore
├── README.md
├── account-analytics
├── README.MD
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com.bobocode
│ │ ├── AccountAnalytics.java
│ │ └── exception
│ │ └── EntityNotFoundException.java
│ └── test
│ └── java
│ └── com
│ └── bobocode
│ └── AccountAnalyticsTest.java
├── account-data
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── bobocode
│ ├── data
│ └── Accounts.java
│ └── model
│ ├── Account.java
│ └── Sex.java
├── crazy-lambdas
├── README.md
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── bobocode
│ │ └── CrazyLambdas.java
│ └── test
│ └── java
│ └── com
│ └── bobocode
│ └── CrazyLambdasTest.java
├── math-functions
├── README.MD
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com.bobocode
│ │ ├── FunctionMap.java
│ │ ├── Functions.java
│ │ └── InvalidFunctionNameException.java
│ └── test
│ └── java
│ └── com
│ └── bobocode
│ └── FunctionsTest.java
├── pom.xml
└── sum-of-squares
├── README.MD
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── bobocode
│ ├── SumOfSquares.java
│ └── exception
│ └── InvalidRangeException.java
└── test
└── java
└── com
└── bobocode
└── SumOfSquareTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | **/*.iml
3 | **/target
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This repo is DEPRECATED. Please use [java-fundamentals-course](https://github.com/bobocode-projects/java-fundamentals-course)
2 | #
Java 8 exercises
3 | The list of exercises dedicated to training your Java 8 and functional programming skills
4 |
5 | ### No pain, No gain :heavy_exclamation_mark:
6 |
7 | > Skill is only developed by hours and hours and hours of beating on your craft
8 |
9 | Working on real problems, you're focused on finding a solution. Learning new things, you're trying to understand how it works.
10 | It is important to have a different type of activities, which purpose is improving your skill
11 |
12 | ***An exercise** is a predefined task that you continuously implement to improve a certain skill* :muscle:
13 | ##
14 | * [Math functions](https://github.com/bobocode-projects/java-8-exercises/tree/master/math-functions)
15 | * [Account analytics](https://github.com/bobocode-projects/java-functional-features-exercises/tree/master/account-analytics)
16 | * [Sum of squares](https://github.com/bobocode-projects/java-functional-features-exercises/tree/master/sum-of-squares)
17 | * [Crazy lambdas](https://github.com/bobocode-projects/java-functional-features-exercises/tree/master/crazy-lambdas)
18 |
--------------------------------------------------------------------------------
/account-analytics/README.MD:
--------------------------------------------------------------------------------
1 | #
Account analytics exercise :muscle:
2 | Improve your Stream API skills
3 | ### Task
4 | `AccountAnalytics` provides an API with a couple statistic methods for a list of accounts. Your job is to implement the *todo* section of that class using **Stream API**.
5 | To verify your implementation, run `AccountAnalyticsTest.java`
6 |
7 | ### Pre-conditions :heavy_exclamation_mark:
8 | You're supposed to be familiar with Java 8
9 |
10 | ### How to start :question:
11 | * Just clone the repository and start implementing the **todo** section, verify your changes by running tests
12 | * If you don't have enough knowledge about this domain, check out the [links below](#related-materials-information_source)
13 | * Don't worry if you got stuck, checkout the **exercise/completed** branch and see the final implementation
14 |
15 | ### Related materials :information_source:
16 | * [Stream API tutorial](https://github.com/bobocode-projects/java-functional-features-tutorial/blob/master/stream-api/README.MD)
17 | * [State of lambda (JSR 335)](http://htmlpreview.github.io/?https://github.com/bobocode-projects/resources/blob/master/java8/lambda/sotl.html)
18 |
19 |
--------------------------------------------------------------------------------
/account-analytics/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java-functional-features-exercises
7 | com.bobocode
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | account-analytics
13 |
14 |
15 |
16 | com.bobocode
17 | account-data
18 | 1.0-SNAPSHOT
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/account-analytics/src/main/java/com.bobocode/AccountAnalytics.java:
--------------------------------------------------------------------------------
1 | package com.bobocode;
2 |
3 | import com.bobocode.exception.EntityNotFoundException;
4 | import com.bobocode.model.Account;
5 |
6 | import java.math.BigDecimal;
7 | import java.time.Month;
8 | import java.util.*;
9 |
10 | import static java.util.stream.Collectors.mapping;
11 | import static java.util.stream.Collectors.toMap;
12 |
13 | /**
14 | * Implement methods using Stream API
15 | */
16 | public class AccountAnalytics {
17 | private Collection accounts;
18 |
19 | public static AccountAnalytics of(Collection accounts) {
20 | return new AccountAnalytics(accounts);
21 | }
22 |
23 | private AccountAnalytics(Collection accounts) {
24 | this.accounts = accounts;
25 | }
26 |
27 | /**
28 | * Returns {@link Optional} that contains an {@link Account} with the max value of balance
29 | *
30 | * @return account with max balance wrapped with optional
31 | */
32 | public Optional findRichestPerson() {
33 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
34 | }
35 |
36 | /**
37 | * Returns a {@link List} of {@link Account} that have a birthday month equal to provided.
38 | *
39 | * @param birthdayMonth a month of birth
40 | * @return a list of accounts
41 | */
42 | public List findAccountsByBirthdayMonth(Month birthdayMonth) {
43 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
44 | }
45 |
46 | /**
47 | * Returns a map that separates all accounts into two lists - male and female. Map has two keys {@code true} indicates
48 | * male list, and {@code false} indicates female list.
49 | *
50 | * @return a map where key is true or false, and value is list of male, and female accounts
51 | */
52 | public Map> partitionMaleAccounts() {
53 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
54 | }
55 |
56 | /**
57 | * Returns a {@link Map} that stores accounts grouped by its email domain. A map key is {@link String} which is an
58 | * email domain like "gmail.com". And the value is a {@link List} of {@link Account} objects with a specific email domain.
59 | *
60 | * @return a map where key is an email domain and value is a list of all account with such email
61 | */
62 | public Map> groupAccountsByEmailDomain() {
63 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
64 | }
65 |
66 | /**
67 | * Returns a number of letters in all first and last names.
68 | *
69 | * @return total number of letters of first and last names of all accounts
70 | */
71 | public int getNumOfLettersInFirstAndLastNames() {
72 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
73 | }
74 |
75 | /**
76 | * Returns a total balance of all accounts.
77 | *
78 | * @return total balance of all accounts
79 | */
80 | public BigDecimal calculateTotalBalance() {
81 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
82 | }
83 |
84 | /**
85 | * Returns a {@link List} of {@link Account} objects sorted by first and last names.
86 | *
87 | * @return list of accounts sorted by first and last names
88 | */
89 | public List sortByFirstAndLastNames() {
90 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
91 | }
92 |
93 | /**
94 | * Checks if there is at least one account with provided email domain.
95 | *
96 | * @param emailDomain
97 | * @return true if there is an account that has an email with provided domain
98 | */
99 | public boolean containsAccountWithEmailDomain(String emailDomain) {
100 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
101 | }
102 |
103 | /**
104 | * Returns account balance by its email. Throws {@link EntityNotFoundException} with message
105 | * "Cannot find Account by email={email}" if account is not found.
106 | *
107 | * @param email account email
108 | * @return account balance
109 | */
110 | public BigDecimal getBalanceByEmail(String email) {
111 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
112 | }
113 |
114 | /**
115 | * Collects all existing accounts into a {@link Map} where a key is account id, and the value is {@link Account} instance
116 | *
117 | * @return map of accounts by its ids
118 | */
119 | public Map collectAccountsById() {
120 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
121 | }
122 |
123 | /**
124 | * Filters accounts by the year when an account was created. Collects account balances by its emails into a {@link Map}.
125 | * The key is {@link Account#email} and the value is {@link Account#balance}
126 | *
127 | * @param year the year of account creation
128 | * @return map of account by its ids the were created in a particular year
129 | */
130 | public Map collectBalancesByIdForAccountsCreatedOn(int year) {
131 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
132 | }
133 |
134 | /**
135 | * Returns a {@link Map} where key is {@link Account#lastName} and values is a {@link Set} that contains first names
136 | * of all accounts with a specific last name.
137 | *
138 | * @return a map where key is a last name and value is a set of first names
139 | */
140 | public Map> groupFirstNamesByLastNames() {
141 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
142 | }
143 |
144 | /**
145 | * Returns a {@link Map} where key is a birthday month, and value is a {@link String} that stores comma and space
146 | * -separated first names (e.g. "Polly, Dylan, Clark"), of all accounts that have the same birthday month.
147 | *
148 | * @return a map where a key is a birthday month and value is comma-separated first names
149 | */
150 | public Map groupCommaSeparatedFirstNamesByBirthdayMonth() {
151 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
152 | }
153 |
154 | /**
155 | * Returns a {@link Map} where key is a {@link Month} of {@link Account#creationDate}, and value is total balance
156 | * of all accounts that have the same value creation month.
157 | *
158 | * @return a map where key is a creation month and value is total balance of all accounts created in that month
159 | */
160 | public Map groupTotalBalanceByCreationMonth() {
161 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
162 | }
163 |
164 | /**
165 | * Returns a {@link Map} where key is a letter {@link Character}, and value is a number of its occurrences in
166 | * {@link Account#firstName}.
167 | *
168 | * @return a map where key is a letter and value is its count in all first names
169 | */
170 | public Map getCharacterFrequencyInFirstNames() {
171 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
172 | }
173 |
174 | /**
175 | * Returns a {@link Map} where key is a letter {@link Character}, and value is a number of its occurrences ignoring
176 | * case, in all {@link Account#firstName} and {@link Account#lastName}. All letters should stored in lower case.
177 | *
178 | * @return a map where key is a letter and value is its count ignoring case in all first and last names
179 | */
180 | public Map getCharacterFrequencyIgnoreCaseInFirstAndLastNames() {
181 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
182 | }
183 |
184 | }
185 |
186 |
--------------------------------------------------------------------------------
/account-analytics/src/main/java/com.bobocode/exception/EntityNotFoundException.java:
--------------------------------------------------------------------------------
1 | package com.bobocode.exception;
2 |
3 | public class EntityNotFoundException extends RuntimeException {
4 | public EntityNotFoundException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/account-analytics/src/test/java/com/bobocode/AccountAnalyticsTest.java:
--------------------------------------------------------------------------------
1 | package com.bobocode;
2 |
3 | import com.bobocode.exception.EntityNotFoundException;
4 | import com.bobocode.model.Account;
5 | import com.bobocode.model.Sex;
6 | import org.junit.Before;
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 | import org.junit.runners.JUnit4;
10 |
11 | import java.math.BigDecimal;
12 | import java.time.LocalDate;
13 | import java.time.Month;
14 | import java.util.*;
15 |
16 | import static org.junit.Assert.*;
17 |
18 | /**
19 | * The helper method of this test class do not use Stream API intentionally. You should try to find a stream-based
20 | * solutions for {@link AccountAnalytics} by yourself.
21 | */
22 | @RunWith(JUnit4.class)
23 | public class AccountAnalyticsTest {
24 |
25 | private AccountAnalytics analytics;
26 | private List accounts;
27 |
28 | @Before
29 | public void setUp() {
30 | accounts = Arrays.asList(
31 | new Account(1L, "Justin", "Butler", "justin.butler@gmail.com",
32 | LocalDate.parse("2003-04-17"), Sex.MALE, LocalDate.parse("2016-06-13"), BigDecimal.valueOf(172966)),
33 | new Account(2L, "Olivia", "Cardenas", "cardenas@mail.com",
34 | LocalDate.parse("1930-01-19"), Sex.FEMALE, LocalDate.parse("2014-06-21"), BigDecimal.valueOf(38029)),
35 | new Account(3L, "Nolan", "Donovan", "nolandonovan@gmail.com",
36 | LocalDate.parse("1925-04-19"), Sex.MALE, LocalDate.parse("2011-03-10"), BigDecimal.valueOf(13889)),
37 | new Account(4L, "Lucas", "Lynn", "lucas.lynn@yahoo.com",
38 | LocalDate.parse("1987-05-25"), Sex.MALE, LocalDate.parse("2009-03-05"), BigDecimal.valueOf(16980))
39 | );
40 | analytics = AccountAnalytics.of(accounts);
41 | }
42 |
43 | @Test
44 | public void testFindRichestPerson() {
45 | Optional expectedPerson = Optional.of(accounts.get(0));
46 | Optional actualRichestPerson = analytics.findRichestPerson();
47 |
48 | assertEquals(expectedPerson, actualRichestPerson);
49 | }
50 |
51 | @Test
52 | public void testSeparateMaleAccounts() {
53 | Map> expectedAccountMap = getExpectedMaleMap();
54 | Map> maleToAccountsMap = analytics.partitionMaleAccounts();
55 |
56 | assertEquals(expectedAccountMap, maleToAccountsMap);
57 | }
58 |
59 | private Map> getExpectedMaleMap() {
60 | Map> expectedMap = new HashMap<>(2);
61 | expectedMap.put(Boolean.TRUE, Arrays.asList(accounts.get(0), accounts.get(2), accounts.get(3)));
62 | expectedMap.put(Boolean.FALSE, Arrays.asList(accounts.get(1)));
63 | return expectedMap;
64 | }
65 |
66 | @Test
67 | public void testFindAccountsByBirthdayMonth() {
68 | List expectedList = getExpectedList();
69 | List aprilAccounts = analytics.findAccountsByBirthdayMonth(Month.APRIL);
70 |
71 | assertEquals(expectedList, aprilAccounts);
72 | }
73 |
74 | private List getExpectedList() {
75 | return Arrays.asList(accounts.get(0), accounts.get(2));
76 | }
77 |
78 | @Test
79 | public void testGroupAccountsByEmailDomain() {
80 | Map> expectedEmailMap = getExpectedEmailMap();
81 | Map> emailDomainToAccountsMap = analytics.groupAccountsByEmailDomain();
82 |
83 | assertEquals(expectedEmailMap, emailDomainToAccountsMap);
84 | }
85 |
86 | private Map> getExpectedEmailMap() {
87 | Map> expectedEmailMap = new HashMap<>();
88 | expectedEmailMap.put("gmail.com", Arrays.asList(accounts.get(0), accounts.get(2)));
89 | expectedEmailMap.put("mail.com", Arrays.asList(accounts.get(1)));
90 | expectedEmailMap.put("yahoo.com", Arrays.asList(accounts.get(3)));
91 |
92 | return expectedEmailMap;
93 | }
94 |
95 | @Test
96 | public void testGetNumOfLettersInFirstAndLastNames() {
97 | int numOfLettersInFirstAndLastNames = analytics.getNumOfLettersInFirstAndLastNames();
98 |
99 | assertEquals(47, numOfLettersInFirstAndLastNames);
100 | }
101 |
102 | @Test
103 | public void testCalculateTotalBalance() {
104 | BigDecimal totalBalance = analytics.calculateTotalBalance();
105 |
106 | assertEquals(BigDecimal.valueOf(241864), totalBalance);
107 | }
108 |
109 |
110 | @Test
111 | public void testSortByFirstAndLastNames() {
112 | List sortedList = analytics.sortByFirstAndLastNames();
113 |
114 | assertEquals(1L, sortedList.get(0).getId().longValue());
115 | assertEquals(4L, sortedList.get(1).getId().longValue());
116 | assertEquals(3L, sortedList.get(2).getId().longValue());
117 | assertEquals(2L, sortedList.get(3).getId().longValue());
118 |
119 | }
120 |
121 | @Test
122 | public void testContainsAccountWithEmailDomain() {
123 | assertTrue(analytics.containsAccountWithEmailDomain("gmail.com"));
124 | assertTrue(analytics.containsAccountWithEmailDomain("yahoo.com"));
125 | assertFalse(analytics.containsAccountWithEmailDomain("ukr.net"));
126 | }
127 |
128 | @Test
129 | public void testGetBalanceByEmail() {
130 | Account account = accounts.get(1);
131 | BigDecimal balance = analytics.getBalanceByEmail(account.getEmail());
132 |
133 | assertEquals(account.getBalance(), balance);
134 | }
135 |
136 | @Test
137 | public void testGetBalanceByEmailThrowsException() {
138 | String fakeEmail = "fake@mail.com";
139 | try {
140 | analytics.getBalanceByEmail(fakeEmail);
141 | fail("Should throw exception");
142 | } catch (Exception e) {
143 | assertTrue(e instanceof EntityNotFoundException);
144 | assertEquals(String.format("Cannot find Account by email=%s", fakeEmail), e.getMessage());
145 | }
146 | }
147 |
148 | @Test
149 | public void testCollectAccountsById() {
150 | Map idToAccountMap = analytics.collectAccountsById();
151 |
152 | assertEquals(accounts.get(0), idToAccountMap.get(1L));
153 | assertEquals(accounts.get(1), idToAccountMap.get(2L));
154 | assertEquals(accounts.get(2), idToAccountMap.get(3L));
155 | assertEquals(accounts.get(3), idToAccountMap.get(4L));
156 | }
157 |
158 | @Test
159 | public void testCollectBalancesByIdForAccountsCreatedOn() {
160 | Account account = accounts.get(3);
161 |
162 | Map emailToBalanceMap = analytics.collectBalancesByIdForAccountsCreatedOn(account.getCreationDate().getYear());
163 |
164 | assertEquals(Map.of(account.getEmail(), account.getBalance()), emailToBalanceMap);
165 | }
166 |
167 | @Test
168 | public void testGroupFirstNamesByLastNames() {
169 | Map> lastToFirstNamesMap = analytics.groupFirstNamesByLastNames();
170 |
171 | assertEquals(4, lastToFirstNamesMap.size());
172 | assertEquals(Set.of("Justin"), lastToFirstNamesMap.get("Butler"));
173 | assertEquals(Set.of("Olivia"), lastToFirstNamesMap.get("Cardenas"));
174 | assertEquals(Set.of("Nolan"), lastToFirstNamesMap.get("Donovan"));
175 | assertEquals(Set.of("Lucas"), lastToFirstNamesMap.get("Lynn"));
176 | }
177 |
178 | @Test
179 | public void testGroupCommaSeparatedFirstNamesByBirthdayMonth() {
180 | Map birthdayMonthToFirstNamesMap = analytics.groupCommaSeparatedFirstNamesByBirthdayMonth();
181 |
182 | assertEquals(3, birthdayMonthToFirstNamesMap.size());
183 | assertEquals("Olivia", birthdayMonthToFirstNamesMap.get(Month.JANUARY));
184 | assertEquals("Justin, Nolan", birthdayMonthToFirstNamesMap.get(Month.APRIL));
185 | assertEquals("Lucas", birthdayMonthToFirstNamesMap.get(Month.MAY));
186 | }
187 |
188 | @Test
189 | public void testGroupTotalBalanceByCreationMonth() {
190 | Map totalBalanceByAccountCreationMonth = analytics.groupTotalBalanceByCreationMonth();
191 |
192 | assertEquals(2, totalBalanceByAccountCreationMonth.size());
193 | assertEquals(BigDecimal.valueOf(210995), totalBalanceByAccountCreationMonth.get(Month.JUNE));
194 | assertEquals(BigDecimal.valueOf(30869), totalBalanceByAccountCreationMonth.get(Month.MARCH));
195 | }
196 |
197 | @Test
198 | public void testGetCharacterFrequencyInFirstNames() {
199 | Map characterFrequencyInFirstAndLastNames = analytics.getCharacterFrequencyInFirstNames();
200 |
201 | assertEquals(3, characterFrequencyInFirstAndLastNames.get('a').longValue());
202 | assertEquals(1, characterFrequencyInFirstAndLastNames.get('c').longValue());
203 | assertEquals(3, characterFrequencyInFirstAndLastNames.get('i').longValue());
204 | assertEquals(1, characterFrequencyInFirstAndLastNames.get('J').longValue());
205 | assertEquals(1, characterFrequencyInFirstAndLastNames.get('L').longValue());
206 | assertEquals(2, characterFrequencyInFirstAndLastNames.get('l').longValue());
207 | assertEquals(2, characterFrequencyInFirstAndLastNames.get('u').longValue());
208 | }
209 |
210 | @Test
211 | public void testGetCharacterFrequencyIgnoreCaseInFirstAndLastNames() {
212 | Map characterFrequencyInFirstAndLastNames = analytics.getCharacterFrequencyIgnoreCaseInFirstAndLastNames();
213 |
214 | assertEquals(6, characterFrequencyInFirstAndLastNames.get('a').longValue());
215 | assertEquals(1, characterFrequencyInFirstAndLastNames.get('b').longValue());
216 | assertEquals(2, characterFrequencyInFirstAndLastNames.get('c').longValue());
217 | assertEquals(5, characterFrequencyInFirstAndLastNames.get('l').longValue());
218 | assertEquals(8, characterFrequencyInFirstAndLastNames.get('n').longValue());
219 | assertEquals(3, characterFrequencyInFirstAndLastNames.get('u').longValue());
220 | assertEquals(1, characterFrequencyInFirstAndLastNames.get('y').longValue());
221 | }
222 | }
223 |
224 |
225 |
--------------------------------------------------------------------------------
/account-data/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java-functional-features-exercises
7 | com.bobocode
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | account-data
13 |
14 |
15 |
16 | io.codearte.jfairy
17 | jfairy
18 | 0.5.7
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/account-data/src/main/java/com/bobocode/data/Accounts.java:
--------------------------------------------------------------------------------
1 | package com.bobocode.data;
2 |
3 | import com.bobocode.model.Account;
4 | import com.bobocode.model.Sex;
5 | import io.codearte.jfairy.Fairy;
6 | import io.codearte.jfairy.producer.person.Person;
7 |
8 | import java.math.BigDecimal;
9 | import java.time.LocalDate;
10 | import java.util.List;
11 | import java.util.Random;
12 |
13 | import static java.util.stream.Collectors.toList;
14 | import static java.util.stream.IntStream.range;
15 |
16 | public interface Accounts {
17 | static Account getAccount(){
18 | Fairy fairy = Fairy.create();
19 | Person person = fairy.person();
20 | Random random = new Random();
21 |
22 |
23 | Account fakeAccount = new Account();
24 | fakeAccount.setFirstName(person.getFirstName());
25 | fakeAccount.setLastName(person.getLastName());
26 | fakeAccount.setEmail(person.getEmail());
27 | fakeAccount.setBirthday(LocalDate.of(
28 | person.getDateOfBirth().getYear(),
29 | person.getDateOfBirth().getMonthOfYear(),
30 | person.getDateOfBirth().getDayOfMonth()));
31 | fakeAccount.setSex(Sex.valueOf(person.getSex().name()));
32 | fakeAccount.setBalance(BigDecimal.valueOf(random.nextInt(200_000)));
33 | fakeAccount.setCreationDate(LocalDate.now());
34 |
35 | return fakeAccount;
36 | }
37 |
38 | static List getAccountList(int size){
39 | return range(0, size)
40 | .mapToObj(i -> getAccount())
41 | .collect(toList());
42 | }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/account-data/src/main/java/com/bobocode/model/Account.java:
--------------------------------------------------------------------------------
1 | package com.bobocode.model;
2 |
3 | import lombok.*;
4 |
5 | import java.math.BigDecimal;
6 | import java.time.LocalDate;
7 | import java.time.LocalDateTime;
8 |
9 | @NoArgsConstructor
10 | @AllArgsConstructor(access = AccessLevel.PUBLIC)
11 | @Getter
12 | @Setter
13 | @ToString
14 | @EqualsAndHashCode(of = "email")
15 | public class Account {
16 | private Long id;
17 | private String firstName;
18 | private String lastName;
19 | private String email;
20 | private LocalDate birthday;
21 | private Sex sex;
22 | private LocalDate creationDate;
23 | private BigDecimal balance = BigDecimal.ZERO;
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/account-data/src/main/java/com/bobocode/model/Sex.java:
--------------------------------------------------------------------------------
1 | package com.bobocode.model;
2 |
3 | public enum Sex {
4 | MALE,
5 | FEMALE
6 | }
7 |
--------------------------------------------------------------------------------
/crazy-lambdas/README.md:
--------------------------------------------------------------------------------
1 | #
Crazy lambda exercise :muscle:
2 | Improve your lambda skills
3 | ### Task
4 | `CrazyLambdas` class consists of static methods that return various functions, operations and predicates.
5 | Your job is to implement the *todo* section of that class using **Lambda expressions** and **method reference**.
6 | To verify your implementation, run `CrazyLambdasTest.java`
7 |
8 | ### Pre-conditions :heavy_exclamation_mark:
9 | You're supposed to be familiar with Java 8
10 |
11 | ### How to start :question:
12 | * Just clone the repository and start implementing the **todo** section, verify your changes by running tests
13 | * If you don't have enough knowledge about this domain, check out the [links below](#related-materials-information_source)
14 | * Don't worry if you got stuck, checkout the **exercise/completed** branch and see the final implementation
15 |
16 | ### Related materials :information_source:
17 | * [Lambda tutorial](https://github.com/bobocode-projects/java-8-tutorial/tree/master/lambdas)
18 | * [State of lambda (JSR 335)](http://htmlpreview.github.io/?https://github.com/bobocode-projects/resources/blob/master/java8/lambda/sotl.html)
19 |
20 |
--------------------------------------------------------------------------------
/crazy-lambdas/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java-functional-features-exercises
7 | com.bobocode
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | crazy-lambdas
13 |
14 |
15 |
--------------------------------------------------------------------------------
/crazy-lambdas/src/main/java/com/bobocode/CrazyLambdas.java:
--------------------------------------------------------------------------------
1 | package com.bobocode;
2 |
3 | import java.math.BigDecimal;
4 | import java.util.Map;
5 | import java.util.TreeMap;
6 | import java.util.function.*;
7 |
8 | public class CrazyLambdas {
9 |
10 | /**
11 | * Returns {@link Supplier} that always supply "Hello"
12 | *
13 | * @return a string supplier
14 | */
15 | public static Supplier helloSupplier() {
16 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
17 | }
18 |
19 | /**
20 | * Returns a {@link Predicate} of string that checks if string is empty
21 | *
22 | * @return a string predicate
23 | */
24 | public static Predicate isEmptyPredicate() {
25 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
26 | }
27 |
28 | /**
29 | * Return a {@link Function} that accepts {@link String} and returns that string repeated n time, where n is passed
30 | * as function argument
31 | *
32 | * @return function that repeats Strings
33 | */
34 | public static BiFunction stringMultiplier() {
35 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
36 | }
37 |
38 | /**
39 | * Returns a {@link Function} that converts a {@link BigDecimal} number into a {@link String} that start with
40 | * a dollar sign and then gets a value
41 | *
42 | * @return function that converts adds dollar sign
43 | */
44 | public static Function toDollarStringFunction() {
45 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
46 | }
47 |
48 | /**
49 | * Receives two parameter that represent a range and returns a {@link Predicate} that verifies if string
50 | * length is in the specified range. E.g. min <= length < max
51 | *
52 | * @param min min length
53 | * @param max max length
54 | * @return a string predicate
55 | */
56 | public static Predicate lengthInRangePredicate(int min, int max) {
57 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
58 | }
59 |
60 | /**
61 | * Returns a {@link Supplier} of random integers
62 | *
63 | * @return int supplier
64 | */
65 | public static IntSupplier randomIntSupplier() {
66 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
67 | }
68 |
69 |
70 | /**
71 | * Returns an {@link IntUnaryOperator} that receives an int as a bound parameter, and returns a random int
72 | *
73 | * @return int operation
74 | */
75 | public static IntUnaryOperator boundedRandomIntSupplier() {
76 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
77 | }
78 |
79 | /**
80 | * Returns {@link IntUnaryOperator} that calculates an integer square
81 | *
82 | * @return square operation
83 | */
84 | public static IntUnaryOperator intSquareOperation() {
85 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
86 | }
87 |
88 | /**
89 | * Returns a {@link LongBinaryOperator} sum operation.
90 | *
91 | * @return binary sum operation
92 | */
93 | public static LongBinaryOperator longSumOperation() {
94 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
95 | }
96 |
97 | /**
98 | * Returns a {@link ToIntFunction} that converts string to integer.
99 | *
100 | * @return string to int converter
101 | */
102 | public static ToIntFunction stringToIntConverter() {
103 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
104 | }
105 |
106 | /**
107 | * Receives int parameter n, and returns a {@link Supplier} that supplies {@link IntUnaryOperator}
108 | * that is a function f(x) = n * x
109 | *
110 | * @param n a multiplier
111 | * @return a function supplier
112 | */
113 | public static Supplier nMultiplyFunctionSupplier(int n) {
114 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
115 | }
116 |
117 | /**
118 | * Returns a {@link UnaryOperator} that accepts str to str function and returns the same function composed with trim
119 | *
120 | * @return function that composes functions with trim() function
121 | */
122 | public static UnaryOperator> composeWithTrimFunction() {
123 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
124 | }
125 |
126 | /**
127 | * Receives a {@link Runnable} parameter, and returns a {@link Supplier}. The thread will be started only
128 | * when you call supplier method {@link Supplier#get()}
129 | *
130 | * @param runnable the code you want to tun in new thread
131 | * @return a thread supplier
132 | */
133 | public static Supplier runningThreadSupplier(Runnable runnable) {
134 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
135 | }
136 |
137 | /**
138 | * Returns a {@link Consumer} that accepts {@link Runnable} as a parameter and runs in in a new thread.
139 | *
140 | * @return a runnable consumer
141 | */
142 | public static Consumer newThreadRunnableConsumer() {
143 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
144 | }
145 |
146 | /**
147 | * Returns a {@link Function} that accepts an instance of {@link Runnable} and returns a {@link Supplier} of a
148 | * started {@link Thread} that is created from a given {@link Runnable}
149 | *
150 | * @return a function that transforms runnable into a thread supplier
151 | */
152 | public static Function> runnableToThreadSupplierFunction() {
153 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
154 | }
155 |
156 | /**
157 | * Returns a {@link BiFunction} that has two parameters. First is {@link IntUnaryOperator} which is some integer function.
158 | * Second is {@link IntPredicate} which is some integer condition. And the third is {@link IntUnaryOperator} which is
159 | * a new composed function that uses provided predicate (second parameter of binary function) to verify its input
160 | * parameter. If predicate returns {@code true} it applies a provided integer function
161 | * (first parameter of binary function) and returns a result value, otherwise it returns an element itself.
162 | *
163 | * @return a binary function that receiver predicate and function and compose them to create a new function
164 | */
165 | public static BiFunction functionToConditionalFunction() {
166 | throw new UnsupportedOperationException("It's your job to implement this method"); // todo
167 | }
168 |
169 | /**
170 | * Returns a {@link BiFunction} which first parameter is a {@link Map} where key is a function name, and value is some
171 | * {@link IntUnaryOperator}, and second parameter is a {@link String} which is a function name. If the map contains a
172 | * function by a given name then it is returned by high order function otherwise an identity() is returned.
173 | *
174 | * @return a high-order function that fetches a function from a function map by a given name or returns identity()
175 | */
176 | public static BiFunction