Skip to content

Commit 7c2fa7c

Browse files
author
Daniel Reuter
committed
2 parents 0604f86 + 6fb7af8 commit 7c2fa7c

6 files changed

Lines changed: 166 additions & 25 deletions

File tree

src/main/java/de/codecentric/java8examples/Invoice.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package de.codecentric.java8examples;
22

3+
import java.math.BigDecimal;
34
import java.util.List;
5+
import java.util.stream.Collectors;
46

57
public class Invoice {
68

@@ -20,9 +22,50 @@ public List<InvoiceItem> getItems() {
2022
return items;
2123
}
2224

25+
public BigDecimal getTotal() {
26+
return getItems().stream()
27+
.map(invoice -> invoice
28+
.getPricePerUnit()
29+
.multiply(BigDecimal.valueOf(invoice.getQuantity())))
30+
.collect(Collectors.reducing(
31+
BigDecimal.ZERO,
32+
(sum, elem) -> sum.add(elem)));
33+
}
34+
2335
public Invoice(String sender, String recipient, List<InvoiceItem> items) {
2436
this.sender = sender;
2537
this.recipient = recipient;
2638
this.items = items;
2739
}
40+
41+
@Override
42+
public boolean equals(Object o) {
43+
if (this == o) return true;
44+
if (o == null || getClass() != o.getClass()) return false;
45+
46+
Invoice invoice = (Invoice) o;
47+
48+
if (items != null ? !items.equals(invoice.items) : invoice.items != null) return false;
49+
if (recipient != null ? !recipient.equals(invoice.recipient) : invoice.recipient != null) return false;
50+
if (sender != null ? !sender.equals(invoice.sender) : invoice.sender != null) return false;
51+
52+
return true;
53+
}
54+
55+
@Override
56+
public int hashCode() {
57+
int result = sender != null ? sender.hashCode() : 0;
58+
result = 31 * result + (recipient != null ? recipient.hashCode() : 0);
59+
result = 31 * result + (items != null ? items.hashCode() : 0);
60+
return result;
61+
}
62+
63+
@Override
64+
public String toString() {
65+
return "Invoice{" +
66+
"sender='" + sender + '\'' +
67+
", recipient='" + recipient + '\'' +
68+
", items=" + items +
69+
'}';
70+
}
2871
}

src/main/java/de/codecentric/java8examples/InvoiceItem.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,35 @@ public InvoiceItem(String product, Integer quantity, BigDecimal pricePerUnit) {
2525
this.quantity = quantity;
2626
this.pricePerUnit = pricePerUnit;
2727
}
28+
29+
@Override
30+
public boolean equals(Object o) {
31+
if (this == o) return true;
32+
if (o == null || getClass() != o.getClass()) return false;
33+
34+
InvoiceItem that = (InvoiceItem) o;
35+
36+
if (pricePerUnit != null ? !pricePerUnit.equals(that.pricePerUnit) : that.pricePerUnit != null) return false;
37+
if (product != null ? !product.equals(that.product) : that.product != null) return false;
38+
if (quantity != null ? !quantity.equals(that.quantity) : that.quantity != null) return false;
39+
40+
return true;
41+
}
42+
43+
@Override
44+
public int hashCode() {
45+
int result = product != null ? product.hashCode() : 0;
46+
result = 31 * result + (quantity != null ? quantity.hashCode() : 0);
47+
result = 31 * result + (pricePerUnit != null ? pricePerUnit.hashCode() : 0);
48+
return result;
49+
}
50+
51+
@Override
52+
public String toString() {
53+
return "InvoiceItem{" +
54+
"product='" + product + '\'' +
55+
", quantity=" + quantity +
56+
", pricePerUnit=" + pricePerUnit +
57+
'}';
58+
}
2859
}

src/main/java/de/codecentric/java8examples/streaming/CollectingAndReducing.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package de.codecentric.java8examples.streaming;
22

33
import de.codecentric.java8examples.Invoice;
4+
import de.codecentric.java8examples.InvoiceItem;
45
import de.codecentric.java8examples.Person;
56

67
import java.math.BigDecimal;
78
import java.util.*;
8-
import java.util.stream.Stream;
9+
import java.util.stream.Collectors;
910

1011
/**
1112
* Your task: Implement the following methods and make the tests passs.
@@ -16,26 +17,26 @@ public class CollectingAndReducing {
1617
* Compute the average age of the given list of Persons.
1718
*/
1819
public static Double averageAge(List<Person> persons) {
19-
return Double.valueOf(0);
20+
return 0d;
2021
}
2122

2223
/**
2324
* How old is the oldest person in the given list.
2425
*/
2526
public static Integer maxAge(List<Person> persons) {
26-
return Integer.valueOf(0);
27+
return 0;
2728
}
2829

2930
/**
3031
* Compute Age-Statistics (max, min, average, ...) for the given list of Persons.
3132
*/
32-
public static DoubleSummaryStatistics ageStatistics(List<Person> persons) {
33+
public static IntSummaryStatistics ageStatistics(List<Person> persons) {
3334
return null;
3435
}
3536

3637
/**
3738
* Build a comma-separated list of the firstnames of a list of Persons.
38-
*
39+
* <p/>
3940
* Example-Result: "Maggie, Marge, Mary"
4041
*/
4142
public static String buildCommaSeparatedListOfFirstNames(List<Person> persons) {
@@ -59,23 +60,23 @@ public static Invoice mostExpensiveInvoice(List<Invoice> invoices) {
5960
/**
6061
* Just what the method name says.
6162
*/
62-
public static Map<String, List<Invoice>> groupInvoicesByReceiver(List<Invoice> invoices) {
63+
public static Map<String, List<Invoice>> groupInvoicesByRecipient(List<Invoice> invoices) {
6364
return Collections.emptyMap();
6465
}
6566

6667
/**
6768
* Compute the total amount, that each receiver spent.
68-
*
69+
* <p/>
6970
* Hint: Use the two-argument version of Collectors.groupingBy together with Collectors.mapping.
7071
*/
71-
public static Map<String, BigDecimal> expensesByReceiver(List<Invoice> invoices) {
72+
public static Map<String, BigDecimal> expensesByRecipient(List<Invoice> invoices) {
7273
return Collections.emptyMap();
7374
}
7475

7576
/**
7677
* How many items of each product have been purchased?
7778
*/
78-
public static Map<String, String> countByProduct(List<Invoice> invoices) {
79+
public static Map<String, Integer> countByProduct(List<Invoice> invoices) {
7980
return Collections.emptyMap();
8081
}
8182

@@ -101,7 +102,7 @@ public static Map<String, ProductWithPrice> computeDealerInventory(List<Invoice>
101102
* {"Homer" -> ["Beer", "Burger"]}
102103
*/
103104
public static Map<String, List<String>> favoriteArticlesByBuyer(List<Invoice> invoices) {
104-
return Collections.EMPTY_MAP;
105+
return Collections.emptyMap();
105106
}
106107

107108
public static class ProductWithPrice {

src/main/java/de/codecentric/java8examples/streaming/FilteringAndMapping.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.codecentric.java8examples.streaming;
22

33
import de.codecentric.java8examples.Invoice;
4+
import de.codecentric.java8examples.InvoiceItem;
45
import de.codecentric.java8examples.Person;
56

67
import java.util.Collections;

src/test/java/de/codecentric/java8examples/TestData.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ public static List<Person> listOfPersons() {
2424

2525
public static List<Invoice> listOfInvoices() {
2626
return Arrays.asList(
27-
new Invoice("Moe", "Homer", Arrays.asList(
28-
new InvoiceItem("Beer", 13, BigDecimal.valueOf(1.5)),
29-
new InvoiceItem("Burger", 3, BigDecimal.valueOf(4.5)))),
3027
new Invoice("Crusty Burger", "Homer", Arrays.asList(
3128
new InvoiceItem("Burger", 5, BigDecimal.valueOf(5)),
3229
new InvoiceItem("Coke", 1, BigDecimal.valueOf(5)))),
3330
new Invoice("Crusty Burger", "Bart", Arrays.asList(
3431
new InvoiceItem("Coke", 1, BigDecimal.valueOf(5)))),
32+
new Invoice("Moe", "Homer", Arrays.asList(
33+
new InvoiceItem("Beer", 13, BigDecimal.valueOf(1.5)),
34+
new InvoiceItem("Burger", 3, BigDecimal.valueOf(4.5)))),
3535
new Invoice("Kwik-E-Mart", "Homer", Arrays.asList(
3636
new InvoiceItem("Beer", 9, BigDecimal.valueOf(0.9)),
3737
new InvoiceItem("Chips", 2, BigDecimal.valueOf(0.5)))),

src/test/java/de/codecentric/java8examples/streaming/CollectingAndReducingTest.java

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,129 @@
11
package de.codecentric.java8examples.streaming;
22

33
import de.codecentric.java8examples.Invoice;
4+
import de.codecentric.java8examples.InvoiceItem;
45
import de.codecentric.java8examples.Person;
56
import de.codecentric.java8examples.TestData;
67
import org.junit.Test;
78

8-
import java.util.List;
9+
import java.math.BigDecimal;
10+
import java.util.*;
11+
12+
import static junit.framework.Assert.assertNotNull;
13+
import static org.hamcrest.Matchers.*;
14+
import static org.hamcrest.MatcherAssert.assertThat;
915

1016
/**
1117
* Tests for mapping and filtering feature of the streaming api. Once you have completed the stub-methods in
1218
* {@link FilteringAndMapping}, these tests should pass.
1319
*/
1420
public class CollectingAndReducingTest {
1521
private List<Person> persons = TestData.listOfPersons();
16-
1722
private List<Invoice> invoices = TestData.listOfInvoices();
23+
private List<String> recipients = Arrays.asList("Homer", "Bart", "Marge");
1824

1925
@Test
2026
public void testAverageAge() throws Exception {
21-
27+
assertThat(
28+
CollectingAndReducing.averageAge(persons),
29+
closeTo(30.57D, 0.01));
2230
}
2331

2432
@Test
2533
public void testMaxAge() throws Exception {
26-
34+
assertThat(
35+
CollectingAndReducing.maxAge(persons),
36+
equalTo(46));
2737
}
2838

2939
@Test
3040
public void testAgeStatistics() throws Exception {
31-
41+
IntSummaryStatistics statistic = CollectingAndReducing.ageStatistics(persons);
42+
assertNotNull(statistic);
43+
assertThat(statistic.getAverage(), equalTo(30.571428571428573));
44+
assertThat(statistic.getCount(), equalTo(7l));
45+
assertThat(statistic.getMax(), equalTo(46));
46+
assertThat(statistic.getMin(), equalTo(1));
47+
assertThat(statistic.getSum(), equalTo(214l));
3248
}
3349

3450
@Test
3551
public void testBuildCommaSeparatedListOfFirstNames() throws Exception {
36-
52+
assertThat(
53+
CollectingAndReducing.buildCommaSeparatedListOfFirstNames(persons),
54+
equalTo("Jane, Mary, John, Michael, Chris, Pete, Maggie"));
3755
}
3856

3957
@Test
4058
public void testCheapestProduct() throws Exception {
41-
59+
assertThat(
60+
CollectingAndReducing.cheapestProduct(invoices),
61+
equalTo("Chips"));
4262
}
4363

4464
@Test
4565
public void testMostExpensiveInvoice() throws Exception {
66+
assertThat(
67+
CollectingAndReducing.mostExpensiveInvoice(invoices),
68+
equalTo(invoices.get(2)));
4669

4770
}
4871

4972
@Test
50-
public void testGroupInvoicesByReceiver() throws Exception {
51-
73+
public void testGroupInvoicesByRecipient() throws Exception {
74+
Map<String,List<Invoice>> invoicesByRecipient =
75+
CollectingAndReducing.groupInvoicesByRecipient(invoices);
76+
assertThat(invoicesByRecipient.keySet(), hasSize(recipients.size()));
77+
78+
for (String recipient: recipients) {
79+
for (Invoice invoice: invoices) {
80+
if (recipient.equals(invoice.getRecipient())) {
81+
assertThat(invoicesByRecipient.get(recipient),
82+
hasItem(invoice));
83+
} else {
84+
assertThat(invoicesByRecipient.get(recipient),
85+
not(hasItem(invoice)));
86+
}
87+
}
88+
}
5289
}
5390

5491
@Test
55-
public void testExpensesByReceiver() throws Exception {
56-
92+
public void testExpensesByRecipient() throws Exception {
93+
Map<String,BigDecimal> expencesByRecipient =
94+
CollectingAndReducing.expensesByRecipient(invoices);
95+
assertThat(expencesByRecipient.keySet(), hasSize(recipients.size()));
96+
for (String recipient: recipients) {
97+
BigDecimal expenses = BigDecimal.ZERO;
98+
for (Invoice invoice: invoices) {
99+
if (recipient.equals(invoice.getRecipient())) {
100+
expenses = expenses.add(invoice.getTotal());
101+
}
102+
}
103+
assertThat(expencesByRecipient.get(recipient), equalTo(expenses));
104+
}
57105
}
58106

59107
@Test
60108
public void testCountByProduct() throws Exception {
61-
109+
Map<String, Integer> expected = new HashMap<>();
110+
for (Invoice invoice: invoices) {
111+
for (InvoiceItem item: invoice.getItems()) {
112+
String product = item.getProduct();
113+
if (expected.get(product) == null) {
114+
expected.put(product, Integer.valueOf(0));
115+
}
116+
expected.put(
117+
product,
118+
expected.get(product) + item.getQuantity());
119+
}
120+
}
121+
122+
Map<String, Integer> actual = CollectingAndReducing.countByProduct(invoices);
123+
assertThat(actual.keySet(), hasSize(expected.size()));
124+
for (Map.Entry entry: expected.entrySet()) {
125+
assertThat(actual, hasEntry(entry.getKey(), entry.getValue()));
126+
}
62127
}
63128

64129
@Test

0 commit comments

Comments
 (0)