Skip to content

Commit 1698b06

Browse files
authored
Merge pull request iluwatar#767 from nikhilbarar/collection-pipeline
iluwatar#564: Collection Pipeline pattern
2 parents 038befe + 4ed039d commit 1698b06

File tree

13 files changed

+776
-2
lines changed

13 files changed

+776
-2
lines changed

collection-pipeline/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
layout: pattern
3+
title: Collection Pipeline
4+
folder: collection-pipeline
5+
permalink: /patterns/collection-pipeline/
6+
categories: Functional
7+
tags:
8+
- Java
9+
- Difficulty-Beginner
10+
- Functional
11+
---
12+
13+
## Intent
14+
Collection Pipeline introduces Function Composition and Collection Pipeline, two functional-style patterns that you can combine to iterate collections in your code.
15+
In functional programming, it's common to sequence complex operations through a series of smaller modular functions or operations. The series is called a composition of functions, or a function composition. When a collection of data flows through a function composition, it becomes a collection pipeline. Function Composition and Collection Pipeline are two design patterns frequently used in functional-style programming.
16+
17+
![alt text](./etc/collection-pipeline.png "Collection Pipeline")
18+
19+
## Applicability
20+
Use the Collection Pipeline pattern when
21+
22+
* When you want to perform a sequence of operations where one operation's collected output is fed into the next
23+
* When you use a lot of statements in your code
24+
* When you use a lot of loops in your code
25+
26+
## Credits
27+
28+
* [Function composition and the Collection Pipeline pattern](https://www.ibm.com/developerworks/library/j-java8idioms2/index.html)
29+
* [Martin Fowler](https://martinfowler.com/articles/collection-pipeline/)
30+
* [Java8 Streams](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html)
26.6 KB
Loading
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<class-diagram version="1.2.2" icons="true" always-add-relationships="false" generalizations="true" realizations="true"
3+
associations="true" dependencies="false" nesting-relationships="true" router="FAN">
4+
<class id="1" language="java" name="com.iluwatar.collectionpipeline.App" project="collection-pipeline"
5+
file="/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/App.java" binary="false"
6+
corner="BOTTOM_RIGHT">
7+
<position height="-1" width="-1" x="150" y="100"/>
8+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
9+
sort-features="false" accessors="true" visibility="true">
10+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
11+
<operations public="true" package="true" protected="true" private="true" static="true"/>
12+
</display>
13+
</class>
14+
<class id="2" language="java" name="com.iluwatar.collectionpipeline.ImperativeProgramming"
15+
project="collection-pipeline"
16+
file="/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/ImperativeProgramming.java" binary="false"
17+
corner="BOTTOM_RIGHT">
18+
<position height="-1" width="-1" x="437" y="109"/>
19+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
20+
sort-features="false" accessors="true" visibility="true">
21+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
22+
<operations public="true" package="true" protected="true" private="true" static="true"/>
23+
</display>
24+
</class>
25+
<class id="3" language="java" name="com.iluwatar.collectionpipeline.Car" project="collection-pipeline"
26+
file="/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java" binary="false"
27+
corner="BOTTOM_RIGHT">
28+
<position height="-1" width="-1" x="724" y="339"/>
29+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
30+
sort-features="false" accessors="true" visibility="true">
31+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
32+
<operations public="true" package="true" protected="true" private="true" static="true"/>
33+
</display>
34+
</class>
35+
<class id="4" language="java" name="com.iluwatar.collectionpipeline.CarFactory" project="collection-pipeline"
36+
file="/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/CarFactory.java" binary="false"
37+
corner="BOTTOM_RIGHT">
38+
<position height="-1" width="-1" x="899" y="91"/>
39+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
40+
sort-features="false" accessors="true" visibility="true">
41+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
42+
<operations public="true" package="true" protected="true" private="true" static="true"/>
43+
</display>
44+
</class>
45+
<class id="5" language="java" name="com.iluwatar.collectionpipeline.FunctionalProgramming"
46+
project="collection-pipeline"
47+
file="/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/FunctionalProgramming.java" binary="false"
48+
corner="BOTTOM_RIGHT">
49+
<position height="-1" width="-1" x="1187" y="109"/>
50+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
51+
sort-features="false" accessors="true" visibility="true">
52+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
53+
<operations public="true" package="true" protected="true" private="true" static="true"/>
54+
</display>
55+
</class>
56+
<enumeration id="6" language="java" name="com.iluwatar.collectionpipeline.Category" project="collection-pipeline"
57+
file="/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Category.java" binary="false"
58+
corner="BOTTOM_RIGHT">
59+
<position height="-1" width="-1" x="486" y="339"/>
60+
<display autosize="true" stereotype="true" package="true" initial-value="true" signature="true"
61+
sort-features="false" accessors="true" visibility="true">
62+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
63+
<operations public="true" package="true" protected="true" private="true" static="true"/>
64+
</display>
65+
</enumeration>
66+
<class id="7" language="java" name="com.iluwatar.collectionpipeline.Person" project="collection-pipeline"
67+
file="/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java" binary="false"
68+
corner="BOTTOM_RIGHT">
69+
<position height="-1" width="-1" x="723" y="91"/>
70+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
71+
sort-features="false" accessors="true" visibility="true">
72+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
73+
<operations public="true" package="true" protected="true" private="true" static="true"/>
74+
</display>
75+
</class>
76+
<association id="8">
77+
<end type="SOURCE" refId="7" navigable="false">
78+
<attribute id="9" name="cars"/>
79+
<multiplicity id="10" minimum="0" maximum="2147483647"/>
80+
</end>
81+
<end type="TARGET" refId="3" navigable="true"/>
82+
<display labels="true" multiplicity="true"/>
83+
</association>
84+
<association id="11">
85+
<end type="SOURCE" refId="3" navigable="false">
86+
<attribute id="12" name="category"/>
87+
<multiplicity id="13" minimum="0" maximum="1"/>
88+
</end>
89+
<end type="TARGET" refId="6" navigable="true"/>
90+
<display labels="true" multiplicity="true"/>
91+
</association>
92+
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
93+
sort-features="false" accessors="true" visibility="true">
94+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
95+
<operations public="true" package="true" protected="true" private="true" static="true"/>
96+
</classifier-display>
97+
<association-display labels="true" multiplicity="true"/>
98+
</class-diagram>

collection-pipeline/pom.xml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!--
2+
3+
The MIT License
4+
Copyright (c) 2014 Ilkka Seppälä
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.
23+
24+
-->
25+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
26+
<modelVersion>4.0.0</modelVersion>
27+
<parent>
28+
<groupId>com.iluwatar</groupId>
29+
<artifactId>java-design-patterns</artifactId>
30+
<version>1.20.0-SNAPSHOT</version>
31+
</parent>
32+
<artifactId>collection-pipeline</artifactId>
33+
<dependencies>
34+
<dependency>
35+
<groupId>org.junit.jupiter</groupId>
36+
<artifactId>junit-jupiter-api</artifactId>
37+
<scope>test</scope>
38+
</dependency>
39+
<dependency>
40+
<groupId>org.junit.jupiter</groupId>
41+
<artifactId>junit-jupiter-engine</artifactId>
42+
<scope>test</scope>
43+
</dependency>
44+
</dependencies>
45+
</project>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.collectionpipeline;
24+
25+
import java.util.Arrays;
26+
import java.util.List;
27+
import java.util.Map;
28+
29+
import org.slf4j.Logger;
30+
import org.slf4j.LoggerFactory;
31+
32+
/**
33+
* In imperative-style programming, it is common to use for and while loops for
34+
* most kinds of data processing. Function composition is a simple technique
35+
* that lets you sequence modular functions to create more complex operations.
36+
* When you run data through the sequence, you have a collection pipeline.
37+
* Together, the Function Composition and Collection Pipeline patterns enable
38+
* you to create sophisticated programs where data flow from upstream to
39+
* downstream and is passed through a series of transformations.
40+
*
41+
*/
42+
public class App {
43+
44+
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
45+
46+
/**
47+
* Program entry point.
48+
*
49+
* @param args
50+
* command line args
51+
*/
52+
public static void main(String[] args) {
53+
54+
List<Car> cars = CarFactory.createCars();
55+
56+
List<String> modelsImperative = ImperativeProgramming.getModelsAfter2000(cars);
57+
LOGGER.info(modelsImperative.toString());
58+
59+
List<String> modelsFunctional = FunctionalProgramming.getModelsAfter2000(cars);
60+
LOGGER.info(modelsFunctional.toString());
61+
62+
Map<Category, List<Car>> groupingByCategoryImperative = ImperativeProgramming.getGroupingOfCarsByCategory(cars);
63+
LOGGER.info(groupingByCategoryImperative.toString());
64+
65+
Map<Category, List<Car>> groupingByCategoryFunctional = FunctionalProgramming.getGroupingOfCarsByCategory(cars);
66+
LOGGER.info(groupingByCategoryFunctional.toString());
67+
68+
Person john = new Person(cars);
69+
70+
List<Car> sedansOwnedImperative = ImperativeProgramming.getSedanCarsOwnedSortedByDate(Arrays.asList(john));
71+
LOGGER.info(sedansOwnedImperative.toString());
72+
73+
List<Car> sedansOwnedFunctional = FunctionalProgramming.getSedanCarsOwnedSortedByDate(Arrays.asList(john));
74+
LOGGER.info(sedansOwnedFunctional.toString());
75+
}
76+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.collectionpipeline;
24+
25+
/**
26+
* A Car class that has the properties of make, model, year and category.
27+
*/
28+
public class Car {
29+
private String make;
30+
private String model;
31+
private int year;
32+
private Category category;
33+
34+
/**
35+
* Constructor to create an instance of car.
36+
* @param make the make of the car
37+
* @param model the model of the car
38+
* @param yearOfMake the year of built of the car
39+
* @param category the {@link Category} of the car
40+
*/
41+
public Car(String make, String model, int yearOfMake, Category category) {
42+
this.make = make;
43+
this.model = model;
44+
this.year = yearOfMake;
45+
this.category = category;
46+
}
47+
48+
@Override
49+
public int hashCode() {
50+
final int prime = 31;
51+
int result = 1;
52+
result = prime * result + ((category == null) ? 0 : category.hashCode());
53+
result = prime * result + ((make == null) ? 0 : make.hashCode());
54+
result = prime * result + ((model == null) ? 0 : model.hashCode());
55+
result = prime * result + year;
56+
return result;
57+
}
58+
59+
@Override
60+
public boolean equals(Object obj) {
61+
if (this == obj) {
62+
return true;
63+
}
64+
if (obj == null) {
65+
return false;
66+
}
67+
if (getClass() != obj.getClass()) {
68+
return false;
69+
}
70+
Car other = (Car) obj;
71+
if (category != other.category) {
72+
return false;
73+
}
74+
if (make == null) {
75+
if (other.make != null) {
76+
return false;
77+
}
78+
} else if (!make.equals(other.make)) {
79+
return false;
80+
}
81+
if (model == null) {
82+
if (other.model != null) {
83+
return false;
84+
}
85+
} else if (!model.equals(other.model)) {
86+
return false;
87+
}
88+
if (year != other.year) {
89+
return false;
90+
}
91+
return true;
92+
}
93+
94+
public String getMake() {
95+
return make;
96+
}
97+
98+
public String getModel() {
99+
return model;
100+
}
101+
102+
public int getYear() {
103+
return year;
104+
}
105+
106+
public Category getCategory() {
107+
return category;
108+
}
109+
}

0 commit comments

Comments
 (0)