├── .gitignore
├── README.MD
├── blob
└── Data_Model.jpg
├── pom.xml
└── src
├── main
├── java
│ └── space
│ │ └── gavinklfong
│ │ └── demo
│ │ └── streamapi
│ │ ├── AppCommandRunner.java
│ │ ├── DemoApplication.java
│ │ ├── models
│ │ ├── Customer.java
│ │ ├── Order.java
│ │ └── Product.java
│ │ └── repos
│ │ ├── CustomerRepo.java
│ │ ├── OrderRepo.java
│ │ └── ProductRepo.java
└── resources
│ ├── application.properties
│ ├── data.sql
│ └── table_script.ddl
├── site
└── site.xml
└── test
├── java
└── space
│ └── gavinklfong
│ └── demo
│ └── streamapi
│ └── StreamApiTest.java
└── resources
└── application.properties
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 | dependency-reduced-pom.xml
8 | buildNumber.properties
9 | .mvn/timing.properties
10 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar
11 | .mvn/wrapper/maven-wrapper.jar
12 | /.metadata/
13 | .idea
14 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # Java Stream API Exercises
2 |
3 | ## Introduction
4 |
5 | This GitHub project was created to serve as a playground for practicing Java Stream API. There are 15 exercises which introduce the API usage including filtering, transformation, sorting and the output to various formats.
6 |
7 | It is a Spring Boot project with a example data model, repositories and a set of pre-defined data. The system automatically loads data into H2 in-memory database when the Spring Boot app starts up. Therefore, you can fetch data from database by calling repositories and experiment the usage of Java Stream API.
8 |
9 | ## IDE Setup
10 |
11 | This project depends on Lombok Library which is an awesome code auto generation tool, it greatly simplify the source code. Read [this article](https://blog.devgenius.io/how-to-magically-speed-up-java-coding-76fa1a68e0f4) if you would like to know more about the usage.
12 |
13 | To configure your IDE for the support of Lombok, check out [the official documentation](https://projectlombok.org/setup/overview) for detail.
14 |
15 | ## Data Model
16 |
17 | The example data model consists of Customer, Order and Product. Customers can place multiple orders and each order would contain a number of products.
18 |
19 | 
20 |
21 | ## Exercises
22 |
23 | The exercises and the sample solutions can be found in test source `space.gavinklfong.demo.streamapi.StreamApiTest`
24 |
25 | You may refer to this article for detail walk through about the exercises.
26 |
27 | [15 Practical Exercises Help You Master Java Stream API](https://medium.com/dev-genius/15-practical-exercises-help-you-master-java-stream-api-3f9c86b1cf82)
28 |
--------------------------------------------------------------------------------
/blob/Data_Model.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gavinklfong/stream-api-exercises/ca14b6f438ac9d58911b635a26fc0591fa2ad8e8/blob/Data_Model.jpg
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.4.5
9 |
10 |
11 | space.gavinklfong.demo
12 | streamapi
13 | 0.0.1-SNAPSHOT
14 | demo
15 | Exercises for Java Stream API
16 |
17 | 11
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-data-jpa
23 |
24 |
25 | org.springframework.boot
26 | spring-boot-starter-web
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-devtools
31 | runtime
32 | true
33 |
34 |
35 | com.h2database
36 | h2
37 | runtime
38 |
39 |
40 | org.projectlombok
41 | lombok
42 | true
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-starter-test
47 | test
48 |
49 |
50 |
51 |
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-maven-plugin
56 |
57 |
58 |
59 | org.projectlombok
60 | lombok
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/src/main/java/space/gavinklfong/demo/streamapi/AppCommandRunner.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.boot.CommandLineRunner;
6 | import org.springframework.stereotype.Component;
7 | import space.gavinklfong.demo.streamapi.repos.CustomerRepo;
8 | import space.gavinklfong.demo.streamapi.repos.OrderRepo;
9 | import space.gavinklfong.demo.streamapi.repos.ProductRepo;
10 |
11 | import javax.transaction.Transactional;
12 |
13 | @Slf4j
14 | @Component
15 | public class AppCommandRunner implements CommandLineRunner {
16 |
17 | @Autowired
18 | private CustomerRepo customerRepos;
19 |
20 | @Autowired
21 | private OrderRepo orderRepos;
22 |
23 | @Autowired
24 | private ProductRepo productRepos;
25 |
26 | @Transactional
27 | @Override
28 | public void run(String... args) throws Exception {
29 | log.info("Customers:");
30 | customerRepos.findAll()
31 | .forEach(c -> log.info(c.toString()));
32 |
33 | log.info("Orders:");
34 | orderRepos.findAll()
35 | .forEach(o -> log.info(o.toString()));
36 |
37 | log.info("Products:");
38 | productRepos.findAll()
39 | .forEach(p -> log.info(p.toString()));
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/space/gavinklfong/demo/streamapi/DemoApplication.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class DemoApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(DemoApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/space/gavinklfong/demo/streamapi/models/Customer.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi.models;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.GenerationType;
6 | import javax.persistence.Id;
7 | import javax.persistence.Table;
8 |
9 | import lombok.AllArgsConstructor;
10 | import lombok.Builder;
11 | import lombok.Data;
12 | import lombok.NoArgsConstructor;
13 |
14 | @Builder
15 | @Data
16 | @Entity
17 | @NoArgsConstructor
18 | @AllArgsConstructor
19 | @Table
20 | public class Customer {
21 |
22 | @Id
23 | @GeneratedValue(strategy = GenerationType.IDENTITY)
24 | private Long id;
25 |
26 | private String name;
27 |
28 | private Integer tier;
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/space/gavinklfong/demo/streamapi/models/Order.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi.models;
2 |
3 | import lombok.*;
4 |
5 | import javax.persistence.*;
6 | import java.time.LocalDate;
7 | import java.util.Set;
8 |
9 | @Builder
10 | @Data
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | @Entity
14 | @Table(name = "product_order")
15 | public class Order {
16 |
17 | @Id
18 | @GeneratedValue(strategy = GenerationType.IDENTITY)
19 | private Long id;
20 |
21 | @Column(name="order_date")
22 | private LocalDate orderDate;
23 |
24 | @Column(name="delivery_date")
25 | private LocalDate deliveryDate;
26 |
27 | private String status;
28 |
29 | @ManyToOne
30 | @JoinColumn(name = "customer_id")
31 | private Customer customer;
32 |
33 | @ManyToMany
34 | @JoinTable(
35 | name = "order_product_relationship",
36 | joinColumns = { @JoinColumn(name = "order_id") },
37 | inverseJoinColumns = { @JoinColumn(name = "product_id") }
38 | )
39 | @ToString.Exclude
40 | @EqualsAndHashCode.Exclude
41 | Set products;
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/space/gavinklfong/demo/streamapi/models/Product.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi.models;
2 |
3 | import java.util.Set;
4 |
5 | import javax.persistence.Entity;
6 | import javax.persistence.GeneratedValue;
7 | import javax.persistence.GenerationType;
8 | import javax.persistence.Id;
9 | import javax.persistence.ManyToMany;
10 | import javax.persistence.Table;
11 |
12 | import lombok.AllArgsConstructor;
13 | import lombok.Builder;
14 | import lombok.Data;
15 | import lombok.EqualsAndHashCode;
16 | import lombok.NoArgsConstructor;
17 | import lombok.ToString;
18 | import lombok.With;
19 |
20 | @Builder
21 | @Data
22 | @NoArgsConstructor
23 | @AllArgsConstructor
24 | @Entity
25 | @Table
26 | public class Product {
27 |
28 | @Id
29 | @GeneratedValue(strategy = GenerationType.IDENTITY)
30 | private Long id;
31 |
32 | private String name;
33 |
34 | private String category;
35 |
36 | @With
37 | private Double price;
38 |
39 | @ManyToMany(mappedBy = "products")
40 | @ToString.Exclude
41 | @EqualsAndHashCode.Exclude
42 | private Set orders;
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/space/gavinklfong/demo/streamapi/repos/CustomerRepo.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi.repos;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.repository.CrudRepository;
6 | import org.springframework.stereotype.Repository;
7 |
8 | import space.gavinklfong.demo.streamapi.models.Customer;
9 |
10 | @Repository
11 | public interface CustomerRepo extends CrudRepository {
12 |
13 | List findAll();
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/space/gavinklfong/demo/streamapi/repos/OrderRepo.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi.repos;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.repository.CrudRepository;
6 | import org.springframework.stereotype.Repository;
7 |
8 | import space.gavinklfong.demo.streamapi.models.Order;
9 |
10 | @Repository
11 | public interface OrderRepo extends CrudRepository {
12 |
13 | List findAll();
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/space/gavinklfong/demo/streamapi/repos/ProductRepo.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi.repos;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.repository.CrudRepository;
6 | import org.springframework.stereotype.Repository;
7 |
8 | import space.gavinklfong.demo.streamapi.models.Product;
9 |
10 | @Repository
11 | public interface ProductRepo extends CrudRepository {
12 |
13 | List findAll();
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.hibernate.ddl-auto=update
2 | spring.datasource.url = jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
3 |
4 | spring.jpa.show-sql=false
5 | spring.jpa.properties.hibernate.generate_statistics=false
6 | spring.jpa.properties.hibernate.show_sql=false
7 |
--------------------------------------------------------------------------------
/src/main/resources/data.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO customer (id, name, tier) VALUES (1, 'Stefan Walker', 1);
2 | INSERT INTO customer (id, name, tier) VALUES (2, 'Daija Von', 1);
3 | INSERT INTO customer (id, name, tier) VALUES (3, 'Ariane Rodriguez', 1);
4 | INSERT INTO customer (id, name, tier) VALUES (4, 'Marques Nikolaus', 2);
5 | INSERT INTO customer (id, name, tier) VALUES (5, 'Rachelle Greenfelder', 0);
6 | INSERT INTO customer (id, name, tier) VALUES (6, 'Larissa White', 2);
7 | INSERT INTO customer (id, name, tier) VALUES (7, 'Fae Heidenreich', 1);
8 | INSERT INTO customer (id, name, tier) VALUES (8, 'Dino Will', 2);
9 | INSERT INTO customer (id, name, tier) VALUES (9, 'Eloy Stroman', 1);
10 | INSERT INTO customer (id, name, tier) VALUES (10, 'Brisa O''Connell', 1);
11 | INSERT INTO product (id, name, category, price) VALUES (1, 'omnis quod consequatur', 'Games', 184.83);
12 | INSERT INTO product (id, name, category, price) VALUES (2, 'vel libero suscipit', 'Toys', 12.66);
13 | INSERT INTO product (id, name, category, price) VALUES (3, 'non nemo iure', 'Grocery', 498.02);
14 | INSERT INTO product (id, name, category, price) VALUES (4, 'voluptatem voluptas aspernatur', 'Toys', 536.80);
15 | INSERT INTO product (id, name, category, price) VALUES (5, 'animi cum rem', 'Games', 458.20);
16 | INSERT INTO product (id, name, category, price) VALUES (6, 'dolorem porro debitis', 'Toys', 146.52);
17 | INSERT INTO product (id, name, category, price) VALUES (7, 'aspernatur rerum qui', 'Books', 656.42);
18 | INSERT INTO product (id, name, category, price) VALUES (8, 'deleniti earum et', 'Baby', 41.46);
19 | INSERT INTO product (id, name, category, price) VALUES (9, 'voluptas ut quidem', 'Books', 697.57);
20 | INSERT INTO product (id, name, category, price) VALUES (10, 'eos sed debitis', 'Baby', 366.90);
21 | INSERT INTO product (id, name, category, price) VALUES (11, 'laudantium sit nihil', 'Toys', 95.50);
22 | INSERT INTO product (id, name, category, price) VALUES (12, 'ut perferendis corporis', 'Grocery', 302.19);
23 | INSERT INTO product (id, name, category, price) VALUES (13, 'sint voluptatem ut', 'Toys', 295.37);
24 | INSERT INTO product (id, name, category, price) VALUES (14, 'quos sunt ipsam', 'Grocery', 534.64);
25 | INSERT INTO product (id, name, category, price) VALUES (15, 'qui illo error', 'Baby', 623.58);
26 | INSERT INTO product (id, name, category, price) VALUES (16, 'aut ex ducimus', 'Books', 551.39);
27 | INSERT INTO product (id, name, category, price) VALUES (17, 'accusamus repellendus minus', 'Books', 240.58);
28 | INSERT INTO product (id, name, category, price) VALUES (18, 'aut accusamus quia', 'Baby', 881.38);
29 | INSERT INTO product (id, name, category, price) VALUES (19, 'doloremque incidunt sed', 'Games', 988.49);
30 | INSERT INTO product (id, name, category, price) VALUES (20, 'libero omnis velit', 'Baby', 177.61);
31 | INSERT INTO product (id, name, category, price) VALUES (21, 'consectetur cupiditate sunt', 'Toys', 95.46);
32 | INSERT INTO product (id, name, category, price) VALUES (22, 'itaque ea qui', 'Baby', 677.78);
33 | INSERT INTO product (id, name, category, price) VALUES (23, 'non et nulla', 'Grocery', 70.49);
34 | INSERT INTO product (id, name, category, price) VALUES (24, 'veniam consequatur et', 'Books', 893.44);
35 | INSERT INTO product (id, name, category, price) VALUES (25, 'magnam adipisci voluptate', 'Grocery', 366.13);
36 | INSERT INTO product (id, name, category, price) VALUES (26, 'reiciendis consequuntur placeat', 'Toys', 359.27);
37 | INSERT INTO product (id, name, category, price) VALUES (27, 'dolores ipsum sit', 'Toys', 786.99);
38 | INSERT INTO product (id, name, category, price) VALUES (28, 'ut hic tempore', 'Toys', 316.09);
39 | INSERT INTO product (id, name, category, price) VALUES (29, 'quas quis deserunt', 'Toys', 772.78);
40 | INSERT INTO product (id, name, category, price) VALUES (30, 'excepturi nesciunt accusantium', 'Toys', 911.46);
41 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (1, '2021-02-28', '2021-03-08', 'NEW', 5);
42 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (2, '2021-02-28', '2021-03-05', 'NEW', 3);
43 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (3, '2021-04-10', '2021-04-18', 'DELIVERED', 5);
44 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (4, '2021-03-22', '2021-03-27', 'PENDING', 3);
45 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (5, '2021-03-04', '2021-03-12', 'NEW', 1);
46 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (6, '2021-03-30', '2021-04-07', 'DELIVERED', 9);
47 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (7, '2021-03-05', '2021-03-09', 'PENDING', 8);
48 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (8, '2021-03-27', '2021-04-05', 'NEW', 4);
49 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (9, '2021-04-14', '2021-04-18', 'NEW', 10);
50 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (10, '2021-03-10', '2021-03-19', 'NEW', 8);
51 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (11, '2021-04-01', '2021-04-04', 'DELIVERED', 1);
52 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (12, '2021-02-24', '2021-02-28', 'PENDING', 5);
53 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (13, '2021-03-15', '2021-03-21', 'NEW', 5);
54 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (14, '2021-03-30', '2021-04-07', 'PENDING', 4);
55 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (15, '2021-03-13', '2021-03-14', 'DELIVERED', 5);
56 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (16, '2021-03-13', '2021-03-21', 'NEW', 1);
57 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (17, '2021-03-31', '2021-03-31', 'DELIVERED', 6);
58 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (18, '2021-03-25', '2021-03-31', 'PENDING', 9);
59 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (19, '2021-02-28', '2021-03-09', 'DELIVERED', 9);
60 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (20, '2021-03-23', '2021-03-30', 'NEW', 5);
61 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (21, '2021-03-19', '2021-03-24', 'DELIVERED', 9);
62 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (22, '2021-02-27', '2021-03-01', 'NEW', 5);
63 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (23, '2021-04-19', '2021-04-24', 'PENDING', 4);
64 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (24, '2021-03-24', '2021-03-24', 'DELIVERED', 1);
65 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (25, '2021-03-03', '2021-03-10', 'NEW', 1);
66 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (26, '2021-03-17', '2021-03-26', 'NEW', 10);
67 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (27, '2021-03-20', '2021-03-25', 'NEW', 1);
68 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (28, '2021-04-09', '2021-04-16', 'DELIVERED', 2);
69 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (29, '2021-04-06', '2021-04-08', 'PENDING', 1);
70 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (30, '2021-04-19', '2021-04-20', 'DELIVERED', 1);
71 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (31, '2021-03-03', '2021-03-04', 'NEW', 3);
72 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (32, '2021-03-15', '2021-03-24', 'DELIVERED', 2);
73 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (33, '2021-04-18', '2021-04-24', 'PENDING', 1);
74 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (34, '2021-03-28', '2021-03-28', 'NEW', 6);
75 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (35, '2021-03-15', '2021-03-17', 'NEW', 1);
76 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (36, '2021-03-04', '2021-03-08', 'DELIVERED', 2);
77 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (37, '2021-03-18', '2021-03-25', 'NEW', 8);
78 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (38, '2021-04-11', '2021-04-20', 'NEW', 8);
79 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (39, '2021-04-12', '2021-04-17', 'NEW', 9);
80 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (40, '2021-03-12', '2021-03-12', 'PENDING', 3);
81 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (41, '2021-02-24', '2021-02-26', 'NEW', 5);
82 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (42, '2021-04-08', '2021-04-14', 'DELIVERED', 9);
83 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (43, '2021-03-03', '2021-03-11', 'NEW', 3);
84 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (44, '2021-03-12', '2021-03-14', 'DELIVERED', 4);
85 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (45, '2021-04-01', '2021-04-06', 'DELIVERED', 1);
86 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (46, '2021-03-16', '2021-03-22', 'NEW', 10);
87 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (47, '2021-04-07', '2021-04-12', 'PENDING', 2);
88 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (48, '2021-04-05', '2021-04-06', 'NEW', 2);
89 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (49, '2021-04-10', '2021-04-13', 'NEW', 7);
90 | INSERT INTO product_order (id, order_date, delivery_date, status, customer_id) VALUES (50, '2021-03-18', '2021-03-21', 'NEW', 9);
91 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (1, 19);
92 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (1, 21);
93 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (1, 5);
94 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (2, 17);
95 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (2, 11);
96 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (2, 14);
97 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (2, 13);
98 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (3, 5);
99 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (3, 3);
100 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (3, 19);
101 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (3, 13);
102 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (3, 15);
103 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (4, 22);
104 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (4, 26);
105 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (4, 12);
106 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (5, 5);
107 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (6, 5);
108 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (6, 12);
109 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (7, 8);
110 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (7, 25);
111 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (7, 21);
112 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (7, 1);
113 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (7, 13);
114 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (7, 10);
115 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (8, 12);
116 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (8, 8);
117 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (9, 8);
118 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (10, 14);
119 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (10, 8);
120 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (11, 12);
121 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (11, 6);
122 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (11, 21);
123 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (11, 22);
124 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (11, 27);
125 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (11, 11);
126 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (12, 19);
127 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (12, 13);
128 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (12, 11);
129 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (12, 6);
130 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (13, 11);
131 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (13, 24);
132 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (13, 26);
133 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (13, 23);
134 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (14, 18);
135 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (15, 16);
136 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (15, 13);
137 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (15, 7);
138 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (16, 23);
139 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (16, 29);
140 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (16, 18);
141 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (16, 16);
142 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (16, 22);
143 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (16, 26);
144 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (17, 18);
145 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (17, 4);
146 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (18, 13);
147 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (18, 3);
148 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (18, 27);
149 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (18, 2);
150 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (19, 26);
151 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (19, 22);
152 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (19, 18);
153 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (19, 14);
154 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (19, 15);
155 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (19, 13);
156 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (20, 22);
157 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (21, 21);
158 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (21, 26);
159 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (22, 7);
160 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (22, 6);
161 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (23, 27);
162 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (23, 7);
163 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (23, 11);
164 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (23, 5);
165 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (24, 24);
166 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (24, 2);
167 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (24, 6);
168 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (24, 28);
169 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (24, 4);
170 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (25, 28);
171 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (25, 17);
172 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (25, 2);
173 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (25, 29);
174 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (25, 19);
175 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (26, 4);
176 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (27, 6);
177 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (27, 15);
178 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (27, 24);
179 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (28, 22);
180 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (28, 9);
181 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (29, 22);
182 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (30, 29);
183 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (30, 6);
184 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (30, 8);
185 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (31, 16);
186 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (31, 12);
187 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (31, 28);
188 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (32, 8);
189 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (32, 5);
190 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (33, 12);
191 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (33, 26);
192 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (33, 21);
193 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (33, 23);
194 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (33, 29);
195 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (33, 13);
196 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (34, 1);
197 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (34, 6);
198 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (34, 22);
199 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (34, 19);
200 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (34, 13);
201 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (34, 27);
202 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (35, 5);
203 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (35, 11);
204 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (35, 26);
205 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (35, 9);
206 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (36, 28);
207 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (36, 7);
208 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (37, 15);
209 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (37, 11);
210 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (38, 18);
211 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (38, 11);
212 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (38, 14);
213 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (38, 20);
214 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (38, 7);
215 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (39, 1);
216 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (39, 21);
217 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (40, 12);
218 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (40, 10);
219 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (40, 11);
220 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (40, 29);
221 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (40, 1);
222 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (41, 13);
223 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (41, 19);
224 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (41, 5);
225 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (41, 29);
226 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (41, 14);
227 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (41, 4);
228 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (42, 2);
229 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (43, 6);
230 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (44, 20);
231 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (44, 18);
232 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (44, 8);
233 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (44, 24);
234 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (44, 26);
235 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (44, 13);
236 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (45, 23);
237 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (45, 1);
238 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (45, 25);
239 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (45, 15);
240 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (46, 16);
241 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (46, 24);
242 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (46, 19);
243 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (46, 13);
244 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (46, 11);
245 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (47, 23);
246 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (47, 28);
247 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (47, 20);
248 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (47, 21);
249 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (48, 15);
250 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (48, 3);
251 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (48, 26);
252 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (48, 7);
253 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (48, 19);
254 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (48, 10);
255 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (49, 5);
256 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (49, 13);
257 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (49, 29);
258 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (49, 3);
259 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (49, 12);
260 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (49, 17);
261 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (50, 15);
262 | INSERT INTO order_product_relationship (order_id, product_id) VALUES (50, 16);
263 |
--------------------------------------------------------------------------------
/src/main/resources/table_script.ddl:
--------------------------------------------------------------------------------
1 | create table customer (
2 | id bigint generated by default as identity,
3 | name varchar(255),
4 | tier integer,
5 | primary key (id)
6 | )
7 |
8 |
9 | create table order_product_relationship (
10 | order_id bigint not null,
11 | product_id bigint not null,
12 | primary key (order_id, product_id)
13 | )
14 |
15 | create table product (
16 | id bigint generated by default as identity,
17 | category varchar(255),
18 | name varchar(255),
19 | price double,
20 | primary key (id)
21 | )
22 |
23 | create table product_order (
24 | id bigint generated by default as identity,
25 | order_date date,
26 | customer_id bigint,
27 | primary key (id)
28 | )
29 |
30 | alter table order_product_relationship add constraint FKn8aeo7cic1d0ejbbxu3vxlb4c
31 | foreign key (product_id) references product
32 |
33 | alter table order_product_relationship add constraint FK722amt5gugjshh8fhjt6i66i3
34 | foreign key (order_id) references product_order
35 |
36 | alter table product_order add constraint FKa90wgrcf86ft7kh3pjivc5c5e
37 | foreign key (customer_id) references customer
38 |
39 |
--------------------------------------------------------------------------------
/src/site/site.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 | streamapi
7 | https://maven.apache.org/images/apache-maven-project.png
8 | https://www.apache.org/
9 |
10 |
11 |
12 | https://maven.apache.org/images/maven-logo-black-on-white.png
13 | https://maven.apache.org/
14 |
15 |
16 |
17 | org.apache.maven.skins
18 | maven-fluido-skin
19 | 1.7
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/test/java/space/gavinklfong/demo/streamapi/StreamApiTest.java:
--------------------------------------------------------------------------------
1 | package space.gavinklfong.demo.streamapi;
2 |
3 | import java.time.LocalDate;
4 | import java.util.Comparator;
5 | import java.util.DoubleSummaryStatistics;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.Optional;
10 | import java.util.function.BiFunction;
11 | import java.util.function.BiPredicate;
12 | import java.util.function.Function;
13 | import java.util.function.Predicate;
14 | import java.util.stream.Collectors;
15 |
16 | import org.junit.jupiter.api.DisplayName;
17 | import org.junit.jupiter.api.Test;
18 | import org.springframework.beans.factory.annotation.Autowired;
19 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
20 |
21 | import lombok.extern.slf4j.Slf4j;
22 | import space.gavinklfong.demo.streamapi.models.Customer;
23 | import space.gavinklfong.demo.streamapi.models.Order;
24 | import space.gavinklfong.demo.streamapi.models.Product;
25 | import space.gavinklfong.demo.streamapi.repos.CustomerRepo;
26 | import space.gavinklfong.demo.streamapi.repos.OrderRepo;
27 | import space.gavinklfong.demo.streamapi.repos.ProductRepo;
28 |
29 | @Slf4j
30 | @DataJpaTest
31 | public class StreamApiTest {
32 |
33 | @Autowired
34 | private CustomerRepo customerRepo;
35 |
36 | @Autowired
37 | private OrderRepo orderRepo;
38 |
39 | @Autowired
40 | private ProductRepo productRepo;
41 |
42 | @Test
43 | @DisplayName("Obtain a list of product with category = \"Books\" and price > 100")
44 | public void exercise1() {
45 | long startTime = System.currentTimeMillis();
46 | List result = productRepo.findAll()
47 | .stream()
48 | .filter(p -> p.getCategory().equalsIgnoreCase("Books"))
49 | .filter(p -> p.getPrice() > 100)
50 | .collect(Collectors.toList());
51 | long endTime = System.currentTimeMillis();
52 |
53 | log.info(String.format("exercise 1 - execution time: %1$d ms", (endTime - startTime)));
54 | result.forEach(p -> log.info(p.toString()));
55 | }
56 |
57 | @Test
58 | @DisplayName("Obtain a list of product with category = \"Books\" and price > 100 (using Predicate chaining for filter)")
59 | public void exercise1a() {
60 | Predicate categoryFilter = product -> product.getCategory().equalsIgnoreCase("Books");
61 | Predicate priceFilter = product -> product.getPrice() > 100;
62 |
63 | long startTime = System.currentTimeMillis();
64 | List result = productRepo.findAll()
65 | .stream()
66 | .filter(product -> categoryFilter.and(priceFilter).test(product))
67 | .collect(Collectors.toList());
68 | long endTime = System.currentTimeMillis();
69 |
70 | log.info(String.format("exercise 1a - execution time: %1$d ms", (endTime - startTime)));
71 | result.forEach(p -> log.info(p.toString()));
72 | }
73 |
74 | @Test
75 | @DisplayName("Obtain a list of product with category = \"Books\" and price > 100 (using BiPredicate for filter)")
76 | public void exercise1b() {
77 | BiPredicate categoryFilter = (product, category) -> product.getCategory().equalsIgnoreCase(category);
78 |
79 | long startTime = System.currentTimeMillis();
80 | List result = productRepo.findAll()
81 | .stream()
82 | .filter(product -> categoryFilter.test(product, "Books") && product.getPrice() > 100)
83 | .collect(Collectors.toList());
84 | long endTime = System.currentTimeMillis();
85 |
86 | log.info(String.format("exercise 1b - execution time: %1$d ms", (endTime - startTime)));
87 | result.forEach(p -> log.info(p.toString()));
88 | }
89 |
90 | @Test
91 | @DisplayName("Obtain a list of order with product category = \"Baby\"")
92 | public void exercise2() {
93 | long startTime = System.currentTimeMillis();
94 | List result = orderRepo.findAll()
95 | .stream()
96 | .filter(o ->
97 | o.getProducts()
98 | .stream()
99 | .anyMatch(p -> p.getCategory().equalsIgnoreCase("Baby"))
100 | )
101 | .collect(Collectors.toList());
102 |
103 | long endTime = System.currentTimeMillis();
104 |
105 | log.info(String.format("exercise 2 - execution time: %1$d ms", (endTime - startTime)));
106 | result.forEach(o -> log.info(o.toString()));
107 |
108 | }
109 |
110 | @Test
111 | @DisplayName("Obtain a list of product with category = “Toys” and then apply 10% discount\"")
112 | public void exercise3() {
113 | long startTime = System.currentTimeMillis();
114 |
115 | List result = productRepo.findAll()
116 | .stream()
117 | .filter(p -> p.getCategory().equalsIgnoreCase("Toys"))
118 | .map(p -> p.withPrice(p.getPrice() * 0.9))
119 | .collect(Collectors.toList());
120 |
121 | long endTime = System.currentTimeMillis();
122 | log.info(String.format("exercise 3 - execution time: %1$d ms", (endTime - startTime)));
123 | result.forEach(o -> log.info(o.toString()));
124 |
125 | }
126 |
127 | @Test
128 | @DisplayName("Obtain a list of products ordered by customer of tier 2 between 01-Feb-2021 and 01-Apr-2021")
129 | public void exercise4() {
130 | long startTime = System.currentTimeMillis();
131 | List result = orderRepo.findAll()
132 | .stream()
133 | .filter(o -> o.getCustomer().getTier() == 2)
134 | .filter(o -> o.getOrderDate().compareTo(LocalDate.of(2021, 2, 1)) >= 0)
135 | .filter(o -> o.getOrderDate().compareTo(LocalDate.of(2021, 4, 1)) <= 0)
136 | .flatMap(o -> o.getProducts().stream())
137 | .distinct()
138 | .collect(Collectors.toList());
139 |
140 | long endTime = System.currentTimeMillis();
141 | log.info(String.format("exercise 4 - execution time: %1$d ms", (endTime - startTime)));
142 | result.forEach(o -> log.info(o.toString()));
143 | }
144 |
145 | @Test
146 | @DisplayName("Get the 3 cheapest products of \"Books\" category")
147 | public void exercise5() {
148 | long startTime = System.currentTimeMillis();
149 | // Optional result = productRepo.findAll()
150 | // .stream()
151 | // .filter(p -> p.getCategory().equalsIgnoreCase("Books"))
152 | // .sorted(Comparator.comparing(Product::getPrice))
153 | // .findFirst();
154 |
155 | Optional result = productRepo.findAll()
156 | .stream()
157 | .filter(p -> p.getCategory().equalsIgnoreCase("Books"))
158 | .min(Comparator.comparing(Product::getPrice));
159 |
160 | long endTime = System.currentTimeMillis();
161 | log.info(String.format("exercise 5 - execution time: %1$d ms", (endTime - startTime)));
162 | log.info(result.get().toString());
163 |
164 | }
165 |
166 | @Test
167 | @DisplayName("Get the 3 most recent placed order")
168 | public void exercise6() {
169 | long startTime = System.currentTimeMillis();
170 | List result = orderRepo.findAll()
171 | .stream()
172 | .sorted(Comparator.comparing(Order::getOrderDate).reversed())
173 | .limit(3)
174 | .collect(Collectors.toList());
175 |
176 | long endTime = System.currentTimeMillis();
177 | log.info(String.format("exercise 6 - execution time: %1$d ms", (endTime - startTime)));
178 | result.forEach(o -> log.info(o.toString()));
179 | }
180 |
181 | @Test
182 | @DisplayName("Get a list of products which was ordered on 15-Mar-2021")
183 | public void exercise7() {
184 | long startTime = System.currentTimeMillis();
185 | List result = orderRepo.findAll()
186 | .stream()
187 | .filter(o -> o.getOrderDate().isEqual(LocalDate.of(2021, 3, 15)))
188 | .peek(o -> System.out.println(o.toString()))
189 | .flatMap(o -> o.getProducts().stream())
190 | .distinct()
191 | .collect(Collectors.toList());
192 |
193 | long endTime = System.currentTimeMillis();
194 | log.info(String.format("exercise 7 - execution time: %1$d ms", (endTime - startTime)));
195 | result.forEach(o -> log.info(o.toString()));
196 | }
197 |
198 | @Test
199 | @DisplayName("Calculate the total lump of all orders placed in Feb 2021")
200 | public void exercise8() {
201 | long startTime = System.currentTimeMillis();
202 | double result = orderRepo.findAll()
203 | .stream()
204 | .filter(o -> o.getOrderDate().compareTo(LocalDate.of(2021, 2, 1)) >= 0)
205 | .filter(o -> o.getOrderDate().compareTo(LocalDate.of(2021, 3, 1)) < 0)
206 | .flatMap(o -> o.getProducts().stream())
207 | .mapToDouble(Product::getPrice)
208 | .sum();
209 |
210 | long endTime = System.currentTimeMillis();
211 | log.info(String.format("exercise 8 - execution time: %1$d ms", (endTime - startTime)));
212 | log.info("Total lump sum = " + result);
213 | }
214 |
215 | @Test
216 | @DisplayName("Calculate the total lump of all orders placed in Feb 2021 (using reduce with BiFunction)")
217 | public void exercise8a() {
218 | BiFunction accumulator = (acc, product) -> acc + product.getPrice();
219 |
220 | long startTime = System.currentTimeMillis();
221 | double result = orderRepo.findAll()
222 | .stream()
223 | .filter(o -> o.getOrderDate().compareTo(LocalDate.of(2021, 2, 1)) >= 0)
224 | .filter(o -> o.getOrderDate().compareTo(LocalDate.of(2021, 3, 1)) < 0)
225 | .flatMap(o -> o.getProducts().stream())
226 | .reduce(0D, accumulator, Double::sum);
227 |
228 | long endTime = System.currentTimeMillis();
229 | log.info(String.format("exercise 8a - execution time: %1$d ms", (endTime - startTime)));
230 | log.info("Total lump sum = " + result);
231 | }
232 |
233 | @Test
234 | @DisplayName("Calculate the average price of all orders placed on 15-Mar-2021")
235 | public void exercise9() {
236 | long startTime = System.currentTimeMillis();
237 | double result = orderRepo.findAll()
238 | .stream()
239 | .filter(o -> o.getOrderDate().isEqual(LocalDate.of(2021, 3, 15)))
240 | .flatMap(o -> o.getProducts().stream())
241 | .mapToDouble(Product::getPrice)
242 | .average().getAsDouble();
243 |
244 | long endTime = System.currentTimeMillis();
245 | log.info(String.format("exercise 9 - execution time: %1$d ms", (endTime - startTime)));
246 | log.info("Average = " + result);
247 | }
248 |
249 | @Test
250 | @DisplayName("Obtain statistics summary of all products belong to \"Books\" category")
251 | public void exercise10() {
252 | long startTime = System.currentTimeMillis();
253 | DoubleSummaryStatistics statistics = productRepo.findAll()
254 | .stream()
255 | .filter(p -> p.getCategory().equalsIgnoreCase("Books"))
256 | .mapToDouble(Product::getPrice)
257 | .summaryStatistics();
258 |
259 | long endTime = System.currentTimeMillis();
260 | log.info(String.format("exercise 10 - execution time: %1$d ms", (endTime - startTime)));
261 | log.info(String.format("count = %1$d, average = %2$f, max = %3$f, min = %4$f, sum = %5$f",
262 | statistics.getCount(), statistics.getAverage(), statistics.getMax(), statistics.getMin(), statistics.getSum()));
263 |
264 | }
265 |
266 | @Test
267 | @DisplayName("Obtain a mapping of order id and the order's product count")
268 | public void exercise11() {
269 | long startTime = System.currentTimeMillis();
270 | Map result = orderRepo.findAll()
271 | .stream()
272 | .collect(
273 | Collectors.toMap(
274 | Order::getId,
275 | order -> order.getProducts().size())
276 | );
277 |
278 | long endTime = System.currentTimeMillis();
279 | log.info(String.format("exercise 11 - execution time: %1$d ms", (endTime - startTime)));
280 | log.info(result.toString());
281 | }
282 |
283 | @Test
284 | @DisplayName("Obtain a data map of customer and list of orders")
285 | public void exercise12() {
286 | long startTime = System.currentTimeMillis();
287 | Map> result = orderRepo.findAll()
288 | .stream()
289 | .collect(Collectors.groupingBy(Order::getCustomer));
290 |
291 | long endTime = System.currentTimeMillis();
292 | log.info(String.format("exercise 12 - execution time: %1$d ms", (endTime - startTime)));
293 | log.info(result.toString());
294 | }
295 |
296 | @Test
297 | @DisplayName("Obtain a data map of customer_id and list of order_id(s)")
298 | public void exercise12a() {
299 | long startTime = System.currentTimeMillis();
300 | HashMap> result = orderRepo.findAll()
301 | .stream()
302 | .collect(
303 | Collectors.groupingBy(
304 | order -> order.getCustomer().getId(),
305 | HashMap::new,
306 | Collectors.mapping(Order::getId, Collectors.toList())));
307 | long endTime = System.currentTimeMillis();
308 | log.info(String.format("exercise 12a - execution time: %1$d ms", (endTime - startTime)));
309 | log.info(result.toString());
310 | }
311 |
312 | @Test
313 | @DisplayName("Obtain a data map with order and its total price")
314 | public void exercise13() {
315 | long startTime = System.currentTimeMillis();
316 | Map result = orderRepo.findAll()
317 | .stream()
318 | .collect(
319 | Collectors.toMap(
320 | Function.identity(),
321 | order -> order.getProducts().stream()
322 | .mapToDouble(Product::getPrice).sum())
323 | );
324 |
325 | long endTime = System.currentTimeMillis();
326 | log.info(String.format("exercise 13 - execution time: %1$d ms", (endTime - startTime)));
327 | log.info(result.toString());
328 | }
329 |
330 | @Test
331 | @DisplayName("Obtain a data map with order and its total price (using reduce)")
332 | public void exercise13a() {
333 | long startTime = System.currentTimeMillis();
334 | Map result = orderRepo.findAll()
335 | .stream()
336 | .collect(
337 | Collectors.toMap(
338 | Order::getId,
339 | order -> order.getProducts().stream()
340 | .reduce(0D, (acc, product) -> acc + product.getPrice(), Double::sum)
341 | ));
342 |
343 | long endTime = System.currentTimeMillis();
344 | log.info(String.format("exercise 13a - execution time: %1$d ms", (endTime - startTime)));
345 | log.info(result.toString());
346 | }
347 |
348 | @Test
349 | @DisplayName("Obtain a data map of product name by category")
350 | public void exercise14() {
351 | long startTime = System.currentTimeMillis();
352 | Map> result = productRepo.findAll()
353 | .stream()
354 | .collect(
355 | Collectors.groupingBy(
356 | Product::getCategory,
357 | Collectors.mapping(Product::getName, Collectors.toList()))
358 | );
359 |
360 |
361 | long endTime = System.currentTimeMillis();
362 | log.info(String.format("exercise 14 - execution time: %1$d ms", (endTime - startTime)));
363 | log.info(result.toString());
364 | }
365 |
366 | @Test
367 | @DisplayName("Get the most expensive product per category")
368 | void exercise15() {
369 | long startTime = System.currentTimeMillis();
370 | Map> result = productRepo.findAll()
371 | .stream()
372 | .collect(
373 | Collectors.groupingBy(
374 | Product::getCategory,
375 | Collectors.maxBy(Comparator.comparing(Product::getPrice)))
376 | );
377 | long endTime = System.currentTimeMillis();
378 | log.info(String.format("exercise 15 - execution time: %1$d ms", (endTime - startTime)));
379 | log.info(result.toString());
380 | // result.forEach((k,v) -> {
381 | // log.info("key=" + k + ", value=" + v.get());
382 | // });
383 |
384 | }
385 |
386 | @Test
387 | @DisplayName("Get the most expensive product (by name) per category")
388 | void exercise15a() {
389 | long startTime = System.currentTimeMillis();
390 | Map result = productRepo.findAll()
391 | .stream()
392 | .collect(
393 | Collectors.groupingBy(
394 | Product::getCategory,
395 | Collectors.collectingAndThen(
396 | Collectors.maxBy(Comparator.comparingDouble(Product::getPrice)),
397 | optionalProduct -> optionalProduct.map(Product::getName).orElse(null)
398 | )
399 | ));
400 | long endTime = System.currentTimeMillis();
401 | log.info(String.format("exercise 15a - execution time: %1$d ms", (endTime - startTime)));
402 | log.info(result.toString());
403 | }
404 |
405 | }
406 |
--------------------------------------------------------------------------------
/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.hibernate.ddl-auto=update
2 | spring.datasource.url = jdbc:h2:mem:testdb:DB_CLOSE_ON_EXIT=FALSE
3 |
4 | spring.jpa.show-sql=false
5 | spring.jpa.properties.hibernate.generate_statistics=false
6 | spring.jpa.properties.hibernate.show_sql=false
7 |
--------------------------------------------------------------------------------