diff --git a/.travis.yml b/.travis.yml
index af275508b..a59370c30 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,12 +3,18 @@ language: java
jdk:
- oraclejdk8
+env:
+ global:
+ - GH_REF: github.com/iluwatar/java-design-patterns.git
+ - secure: "LxTDuNS/rBWIvKkaEqr79ImZAe48mCdoYCF41coxNXgNoippo4GIBArknqtv+XvdkiuRZ1yGyj6pn8GU33c/yn+krddTUkVCwTbVatbalW5jhQjDbHYym/JcxaK9ZS/3JTeGcWrBgiPqHEEDhCf26vPZsXoMSeVCEORVKTp1BSg="
+
before_install:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
after_success:
- mvn clean test jacoco:report coveralls:report
+ - bash update-ghpages.sh
# Migration to container-based infrastructure
sudo: false
diff --git a/README.md b/README.md
index 4715c3b9b..77282f569 100644
--- a/README.md
+++ b/README.md
@@ -4,25 +4,12 @@
# Design pattern samples in Java
+[](https://travis-ci.org/iluwatar/java-design-patterns)
+[](https://coveralls.io/r/iluwatar/java-design-patterns?branch=master)
+[](https://scan.coverity.com/projects/5634)
[](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-[](https://travis-ci.org/iluwatar/java-design-patterns) [](https://coveralls.io/r/iluwatar/java-design-patterns?branch=master)
-
-
-
-
-
-
-# Table of Contents
- - Introduction
- - How to contribute
- - Frequently Asked Questions
- - Credits
- - License
-
-
-# Introduction [↑](#top)
+# Introduction
Design patterns are formalized best practices that the programmer can use to
solve common problems when designing an application or system.
@@ -34,72 +21,22 @@ Reusing design patterns helps to prevent subtle issues that can cause major
problems, and it also improves code readability for coders and architects who
are familiar with the patterns.
+# Getting started
-# How to contribute [↑](#top)
+Before you dive into the material, you should be familiar with various
+[Programming/Software Design Principles](http://webpro.github.io/programming-principles/).
+
+Once you are familiar with these concepts you can start drilling down into patterns by any of the following approaches
+
+ - Using difficulty tags, `Difficulty-Beginner`, `Difficulty-Intermediate` & `Difficulty-Expert`.
+ - Using pattern categories, `Creational`, `Behavioral` and others.
+ - Search for a specific pattern. Can't find one? Please report a new pattern [here](https://github.com/iluwatar/java-design-patterns/issues).
+
+# How to contribute
If you are willing to contribute to the project you will find the relevant information in our [developer wiki](https://github.com/iluwatar/java-design-patterns/wiki).
-
-# Frequently asked questions [↑](#top)
-
-**Q: What is the difference between State and Strategy patterns?**
-
-While the implementation is similar they solve different problems. The State
-pattern deals with what state an object is in - it encapsulates state-dependent
-behavior.
-The Strategy pattern deals with how an object performs a certain task - it
-encapsulates an algorithm.
-
-**Q: What is the difference between Strategy and Template Method patterns?**
-
-In Template Method the algorithm is chosen at compile time via inheritance.
-With Strategy pattern the algorithm is chosen at runtime via composition.
-
-**Q: What is the difference between Proxy and Decorator patterns?**
-
-The difference is the intent of the patterns. While Proxy controls access to
-the object Decorator is used to add responsibilities to the object.
-
-**Q: What is the difference between Chain of Responsibility and Intercepting Filter patterns?**
-
-While the implementations look similar there are differences. The Chain of
-Responsibility forms a chain of request processors and the processors are then
-executed one by one until the correct processor is found. In Intercepting
-Filter the chain is constructed from filters and the whole chain is always
-executed.
-
-**Q: What is the difference between Visitor and Double Dispatch patterns?**
-
-The Visitor pattern is a means of adding a new operation to existing classes.
-Double dispatch is a means of dispatching function calls with respect to two
-polymorphic types, rather than a single polymorphic type, which is what
-languages like C++ and Java _do not_ support directly.
-
-**Q: What are the differences between Flyweight and Object Pool patterns?**
-
-They differ in the way they are used.
-
-Pooled objects can simultaneously be used by a single "client" only. For that,
-a pooled object must be checked out from the pool, then it can be used by a
-client, and then the client must return the object back to the pool. Multiple
-instances of identical objects may exist, up to the maximal capacity of the
-pool.
-
-In contrast, a Flyweight object is singleton, and it can be used simultaneously
-by multiple clients.
-
-As for concurrent access, pooled objects can be mutable and they usually don't
-need to be thread safe, as typically, only one thread is going to use a
-specific instance at the same time. Flyweight must either be immutable (the
-best option), or implement thread safety.
-
-As for performance and scalability, pools can become bottlenecks, if all the
-pooled objects are in use and more clients need them, threads will become
-blocked waiting for available object from the pool. This is not the case with
-Flyweight.
-
-
-# Credits [↑](#top)
+# Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
* [Effective Java (2nd Edition)](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)
@@ -113,7 +50,6 @@ Flyweight.
* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
* [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697)
-
-# License [↑](#top)
+# License
This project is licensed under the terms of the MIT license.
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 000000000..0ff943d95
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/factory-method/index.md b/factory-method/index.md
index fa30a4349..8011e42c8 100644
--- a/factory-method/index.md
+++ b/factory-method/index.md
@@ -4,7 +4,9 @@ title: Factory Method
folder: factory-method
permalink: /patterns/factory-method/
categories: Creational
-tags: Java
+tags:
+ - Java
+ - Difficulty-Beginner
---
**Intent:** Define an interface for creating an object, but let subclasses
diff --git a/faq.md b/faq.md
new file mode 100644
index 000000000..b98bc7589
--- /dev/null
+++ b/faq.md
@@ -0,0 +1,67 @@
+---
+layout: page
+title: FAQ
+permalink: /faq/
+icon: fa-question
+page-index: 2
+---
+
+### Q1: What is the difference between State and Strategy patterns? {#Q1}
+
+While the implementation is similar they solve different problems. The State
+pattern deals with what state an object is in - it encapsulates state-dependent
+behavior.
+The Strategy pattern deals with how an object performs a certain task - it
+encapsulates an algorithm.
+
+### Q2: What is the difference between Strategy and Template Method patterns? {#Q2}
+
+In Template Method the algorithm is chosen at compile time via inheritance.
+With Strategy pattern the algorithm is chosen at runtime via composition.
+
+### Q3: What is the difference between Proxy and Decorator patterns? {#Q3}
+
+The difference is the intent of the patterns. While Proxy controls access to
+the object Decorator is used to add responsibilities to the object.
+
+### Q4: What is the difference between Chain of Responsibility and Intercepting Filter patterns? {#Q4}
+
+While the implementations look similar there are differences. The Chain of
+Responsibility forms a chain of request processors and the processors are then
+executed one by one until the correct processor is found. In Intercepting
+Filter the chain is constructed from filters and the whole chain is always
+executed.
+
+### Q5: What is the difference between Visitor and Double Dispatch patterns? {#Q5}
+
+The Visitor pattern is a means of adding a new operation to existing classes.
+Double dispatch is a means of dispatching function calls with respect to two
+polymorphic types, rather than a single polymorphic type, which is what
+languages like C++ and Java _do not_ support directly.
+
+### Q6: What are the differences between Flyweight and Object Pool patterns? {#Q6}
+
+They differ in the way they are used.
+
+Pooled objects can simultaneously be used by a single "client" only. For that,
+a pooled object must be checked out from the pool, then it can be used by a
+client, and then the client must return the object back to the pool. Multiple
+instances of identical objects may exist, up to the maximal capacity of the
+pool.
+
+In contrast, a Flyweight object is singleton, and it can be used simultaneously
+by multiple clients.
+
+As for concurrent access, pooled objects can be mutable and they usually don't
+need to be thread safe, as typically, only one thread is going to use a
+specific instance at the same time. Flyweight must either be immutable (the
+best option), or implement thread safety.
+
+As for performance and scalability, pools can become bottlenecks, if all the
+pooled objects are in use and more clients need them, threads will become
+blocked waiting for available object from the pool. This is not the case with
+Flyweight.
+
+### Q7: What are the differences between FluentInterface and Builder patterns? {#Q7}
+
+Fluent interfaces are sometimes confused with the Builder pattern, because they share method chaining and a fluent usage. However, fluent interfaces are not primarily used to create shared (mutable) objects, but to configure complex objects without having to respecify the target object on every property change.
\ No newline at end of file
diff --git a/fluentinterface/etc/fluentinterface.png b/fluentinterface/etc/fluentinterface.png
new file mode 100644
index 000000000..611fec7c6
Binary files /dev/null and b/fluentinterface/etc/fluentinterface.png differ
diff --git a/fluentinterface/etc/fluentinterface.ucls b/fluentinterface/etc/fluentinterface.ucls
new file mode 100644
index 000000000..aab2c9ad7
--- /dev/null
+++ b/fluentinterface/etc/fluentinterface.ucls
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/fluentinterface/index.md b/fluentinterface/index.md
new file mode 100644
index 000000000..27a4d1a26
--- /dev/null
+++ b/fluentinterface/index.md
@@ -0,0 +1,42 @@
+---
+layout: pattern
+title: Fluent Interface
+folder: fluentinterface
+permalink: /patterns/fluentinterface/
+categories: Other
+tags:
+ - Java
+ - Difficulty-Intermediate
+---
+
+**Intent:** A fluent interface provides an easy-readable, flowing interface, that often mimics a domain specific language. Using this pattern results in code that can be read nearly as human language.
+
+**Implementation:**
+
+A fluent interface can be implemented using any of
+
+ * Method Chaining - calling a method returns some object on which further methods can be called.
+ * Static Factory Methods and Imports
+ * Named parameters - can be simulated in Java using static factory methods.
+
+
+
+
+**Applicability:** Use the Fluent Interface pattern when
+
+* you provide an API that would benefit from a DSL-like usage
+* you have objects that are difficult to configure or use
+
+**Real world examples:**
+
+* [Java 8 Stream API](http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html)
+* [Google Guava FluentInterable](https://github.com/google/guava/wiki/FunctionalExplained)
+* [JOOQ](http://www.jooq.org/doc/3.0/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder/)
+* [Mockito](http://mockito.org/)
+* [Java Hamcrest](http://code.google.com/p/hamcrest/wiki/Tutorial)
+
+**Credits**
+
+* [Fluent Interface - Martin Fowler](http://www.martinfowler.com/bliki/FluentInterface.html)
+* [Evolutionary architecture and emergent design: Fluent interfaces - Neal Ford](http://www.ibm.com/developerworks/library/j-eaed14/)
+* [Internal DSL](http://www.infoq.com/articles/internal-dsls-java)
diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml
new file mode 100644
index 000000000..be8ab8039
--- /dev/null
+++ b/fluentinterface/pom.xml
@@ -0,0 +1,20 @@
+
+
+
+ java-design-patterns
+ com.iluwatar
+ 1.6.0
+
+ 4.0.0
+
+ fluentinterface
+
+
+ junit
+ junit
+ test
+
+
+
\ No newline at end of file
diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/App.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/App.java
new file mode 100644
index 000000000..f7352fe39
--- /dev/null
+++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/App.java
@@ -0,0 +1,103 @@
+package com.iluwatar.fluentinterface;
+
+import com.iluwatar.fluentinterface.fluentiterable.FluentIterable;
+import com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable;
+import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import static java.lang.String.valueOf;
+
+/**
+ * Fluent interface pattern is useful when you want to provide an easy readable, flowing API. Those
+ * interfaces tend to mimic domain specific languages, so they can nearly be read as human
+ * languages.
+ *
+ * In this example two implementations of a {@link FluentIterable} interface are given. The
+ * SimpleFluentIterable evaluates eagerly and would be too costly for real world applications. The
+ * LazyFluentIterable is evaluated on termination. Their usage is demonstrated with a simple number
+ * list that is filtered, transformed and collected. The result is printed afterwards.
+ *
+ */
+public class App {
+
+ public static void main(String[] args) {
+
+ List integerList = new ArrayList<>();
+ integerList.addAll(Arrays.asList(
+ 1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97,
+ 45, 23, 2, -68, 45
+ ));
+
+ prettyPrint("The initial list contains: ", integerList);
+
+ List firstFiveNegatives =
+ SimpleFluentIterable.fromCopyOf(integerList).filter(negatives()).first(3).asList();
+ prettyPrint("The first three negative values are: ", firstFiveNegatives);
+
+
+ List lastTwoPositives =
+ SimpleFluentIterable.fromCopyOf(integerList).filter(positives()).last(2).asList();
+ prettyPrint("The last two positive values are: ", lastTwoPositives);
+
+ SimpleFluentIterable
+ .fromCopyOf(integerList)
+ .filter(number -> number % 2 == 0)
+ .first()
+ .ifPresent(
+ evenNumber -> System.out.println(String.format("The first even number is: %d",
+ evenNumber)));
+
+
+ List transformedList =
+ SimpleFluentIterable.fromCopyOf(integerList).filter(negatives()).map(transformToString())
+ .asList();
+ prettyPrint("A string-mapped list of negative numbers contains: ", transformedList);
+
+
+ List lastTwoOfFirstFourStringMapped =
+ LazyFluentIterable.from(integerList).filter(positives()).first(4).last(2)
+ .map(number -> "String[" + String.valueOf(number) + "]").asList();
+ prettyPrint(
+ "The lazy list contains the last two of the first four positive numbers mapped to Strings: ",
+ lastTwoOfFirstFourStringMapped);
+
+ LazyFluentIterable
+ .from(integerList)
+ .filter(negatives())
+ .first(2)
+ .last()
+ .ifPresent(
+ lastOfFirstTwo -> System.out.println(String.format(
+ "The last of the first two negatives is: %d", lastOfFirstTwo)));
+ }
+
+ private static Function transformToString() {
+ return integer -> "String[" + valueOf(integer) + "]";
+ }
+
+ private static Predicate super Integer> negatives() {
+ return integer -> (integer < 0);
+ }
+
+ private static Predicate super Integer> positives() {
+ return integer -> (integer > 0);
+ }
+
+ private static void prettyPrint(String prefix, Iterable iterable) {
+ prettyPrint(", ", prefix, ".", iterable);
+ }
+
+ private static void prettyPrint(String delimiter, String prefix, String suffix,
+ Iterable iterable) {
+ StringJoiner joiner = new StringJoiner(delimiter, prefix, ".");
+ Iterator iterator = iterable.iterator();
+ while (iterator.hasNext()) {
+ joiner.add(iterator.next().toString());
+ }
+
+ System.out.println(joiner);
+ }
+}
diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterable.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterable.java
new file mode 100644
index 000000000..5c4df0391
--- /dev/null
+++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterable.java
@@ -0,0 +1,89 @@
+package com.iluwatar.fluentinterface.fluentiterable;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * The FluentIterable is a more convenient implementation of the common iterable interface based on
+ * the fluent interface design pattern. This interface defines common operations, but doesn't aim to
+ * be complete. It was inspired by Guava's com.google.common.collect.FluentIterable.
+ *
+ * @param is the class of objects the iterable contains
+ */
+public interface FluentIterable extends Iterable {
+
+ /**
+ * Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy
+ * the predicate.
+ *
+ * @param predicate the condition to test with for the filtering. If the test is negative, the
+ * tested object is removed by the iterator.
+ * @return a filtered FluentIterable
+ */
+ FluentIterable filter(Predicate super TYPE> predicate);
+
+ /**
+ * Returns an Optional containing the first element of this iterable if present, else returns
+ * Optional.empty().
+ *
+ * @return the first element after the iteration is evaluated
+ */
+ Optional first();
+
+ /**
+ * Evaluates the iteration and leaves only the count first elements.
+ *
+ * @return the first count elements as an Iterable
+ */
+ FluentIterable first(int count);
+
+ /**
+ * Evaluates the iteration and returns the last element. This is a terminating operation.
+ *
+ * @return the last element after the iteration is evaluated
+ */
+ Optional last();
+
+ /**
+ * Evaluates the iteration and leaves only the count last elements.
+ *
+ * @return the last counts elements as an Iterable
+ */
+ FluentIterable last(int count);
+
+ /**
+ * Transforms this FluentIterable into a new one containing objects of the type NEW_TYPE.
+ *
+ * @param function a function that transforms an instance of TYPE into an instance of NEW_TYPE
+ * @param the target type of the transformation
+ * @return a new FluentIterable of the new type
+ */
+ FluentIterable map(Function super TYPE, NEW_TYPE> function);
+
+ /**
+ * Returns the contents of this Iterable as a List.
+ *
+ * @return a List representation of this Iterable
+ */
+ List asList();
+
+ /**
+ * Utility method that iterates over iterable and adds the contents to a list.
+ *
+ * @param iterable the iterable to collect
+ * @param the type of the objects to iterate
+ * @return a list with all objects of the given iterator
+ */
+ static List copyToList(Iterable iterable) {
+ ArrayList copy = new ArrayList<>();
+ Iterator iterator = iterable.iterator();
+ while (iterator.hasNext()) {
+ copy.add(iterator.next());
+ }
+ return copy;
+ }
+}
diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java
new file mode 100644
index 000000000..e80356d8e
--- /dev/null
+++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java
@@ -0,0 +1,60 @@
+package com.iluwatar.fluentinterface.fluentiterable.lazy;
+
+import java.util.Iterator;
+
+/**
+ * This class is used to realize LazyFluentIterables. It decorates a given iterator. Does not
+ * support consecutive hasNext() calls.
+ *
+ * @param
+ */
+public abstract class DecoratingIterator implements Iterator {
+
+ protected final Iterator fromIterator;
+
+ private TYPE next = null;
+
+ /**
+ * Creates an iterator that decorates the given iterator.
+ *
+ * @param fromIterator
+ */
+ public DecoratingIterator(Iterator fromIterator) {
+ this.fromIterator = fromIterator;
+ }
+
+ /**
+ * Precomputes and saves the next element of the Iterable. null is considered as end of data.
+ *
+ * @return true if a next element is available
+ */
+ @Override
+ public final boolean hasNext() {
+ next = computeNext();
+ return next != null;
+ }
+
+ /**
+ * Returns the next element of the Iterable.
+ *
+ * @return the next element of the Iterable, or null if not present.
+ */
+ @Override
+ public final TYPE next() {
+ if (next == null) {
+ return fromIterator.next();
+ } else {
+ final TYPE result = next;
+ next = null;
+ return result;
+ }
+ }
+
+ /**
+ * Computes the next object of the Iterable. Can be implemented to realize custom behaviour for an
+ * iteration process. null is considered as end of data.
+ *
+ * @return the next element of the Iterable.
+ */
+ public abstract TYPE computeNext();
+}
diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java
new file mode 100644
index 000000000..560b10189
--- /dev/null
+++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java
@@ -0,0 +1,230 @@
+package com.iluwatar.fluentinterface.fluentiterable.lazy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import com.iluwatar.fluentinterface.fluentiterable.FluentIterable;
+
+/**
+ * This is a lazy implementation of the FluentIterable interface. It evaluates all chained
+ * operations when a terminating operation is applied.
+ *
+ * @param the type of the objects the iteration is about
+ */
+public class LazyFluentIterable implements FluentIterable {
+
+ private final Iterable iterable;
+
+ /**
+ * This constructor creates a new LazyFluentIterable. It wraps the given iterable.
+ *
+ * @param iterable the iterable this FluentIterable works on.
+ */
+ protected LazyFluentIterable(Iterable iterable) {
+ this.iterable = iterable;
+ }
+
+ /**
+ * This constructor can be used to implement anonymous subclasses of the LazyFluentIterable.
+ */
+ protected LazyFluentIterable() {
+ iterable = this;
+ }
+
+ /**
+ * Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy
+ * the predicate.
+ *
+ * @param predicate the condition to test with for the filtering. If the test is negative, the
+ * tested object is removed by the iterator.
+ * @return a new FluentIterable object that decorates the source iterable
+ */
+ @Override
+ public FluentIterable filter(Predicate super TYPE> predicate) {
+ return new LazyFluentIterable() {
+ @Override
+ public Iterator iterator() {
+ return new DecoratingIterator(iterable.iterator()) {
+ @Override
+ public TYPE computeNext() {
+ while (fromIterator.hasNext()) {
+ TYPE candidate = fromIterator.next();
+ if (!predicate.test(candidate)) {
+ continue;
+ }
+ return candidate;
+ }
+
+ return null;
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Can be used to collect objects from the iteration. Is a terminating operation.
+ *
+ * @return an Optional containing the first object of this Iterable
+ */
+ @Override
+ public Optional first() {
+ Iterator resultIterator = first(1).iterator();
+ return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
+ }
+
+ /**
+ * Can be used to collect objects from the iteration.
+ *
+ * @param count defines the number of objects to return
+ * @return the same FluentIterable with a collection decimated to a maximum of 'count' first
+ * objects.
+ */
+ @Override
+ public FluentIterable first(int count) {
+ return new LazyFluentIterable() {
+ @Override
+ public Iterator iterator() {
+ return new DecoratingIterator(iterable.iterator()) {
+ int currentIndex = 0;
+
+ @Override
+ public TYPE computeNext() {
+ if (currentIndex < count) {
+ if (fromIterator.hasNext()) {
+ TYPE candidate = fromIterator.next();
+ currentIndex++;
+ return candidate;
+ }
+ }
+ return null;
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Can be used to collect objects from the iteration. Is a terminating operation.
+ *
+ * @return an Optional containing the last object of this Iterable
+ */
+ @Override
+ public Optional last() {
+ Iterator resultIterator = last(1).iterator();
+ return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
+ }
+
+ /**
+ * Can be used to collect objects from the Iterable. Is a terminating operation. This operation is
+ * memory intensive, because the contents of this Iterable are collected into a List, when the
+ * next object is requested.
+ *
+ * @param count defines the number of objects to return
+ * @return the same FluentIterable with a collection decimated to a maximum of 'count' last
+ * objects
+ */
+ @Override
+ public FluentIterable last(int count) {
+ return new LazyFluentIterable() {
+ @Override
+ public Iterator iterator() {
+ return new DecoratingIterator(iterable.iterator()) {
+ private int stopIndex;
+ private int totalElementsCount;
+ private List list;
+ private int currentIndex = 0;
+
+ @Override
+ public TYPE computeNext() {
+ initialize();
+
+ TYPE candidate = null;
+ while (currentIndex < stopIndex && fromIterator.hasNext()) {
+ currentIndex++;
+ fromIterator.next();
+ }
+ if (currentIndex >= stopIndex && fromIterator.hasNext()) {
+ candidate = fromIterator.next();
+ }
+ return candidate;
+ }
+
+ private void initialize() {
+ if (list == null) {
+ list = new ArrayList<>();
+ Iterator newIterator = iterable.iterator();
+ while (newIterator.hasNext()) {
+ list.add(newIterator.next());
+ }
+
+ totalElementsCount = list.size();
+ stopIndex = totalElementsCount - count;
+ }
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Transforms this FluentIterable into a new one containing objects of the type NEW_TYPE.
+ *
+ * @param function a function that transforms an instance of TYPE into an instance of NEW_TYPE
+ * @param the target type of the transformation
+ * @return a new FluentIterable of the new type
+ */
+ @Override
+ public FluentIterable map(Function super TYPE, NEW_TYPE> function) {
+ return new LazyFluentIterable() {
+ @Override
+ public Iterator iterator() {
+ return new DecoratingIterator(null) {
+ Iterator oldTypeIterator = iterable.iterator();
+
+ @Override
+ public NEW_TYPE computeNext() {
+ while (oldTypeIterator.hasNext()) {
+ TYPE candidate = oldTypeIterator.next();
+ return function.apply(candidate);
+ }
+ return null;
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Collects all remaining objects of this iteration into a list.
+ *
+ * @return a list with all remaining objects of this iteration
+ */
+ @Override
+ public List asList() {
+ List copy = FluentIterable.copyToList(iterable);
+ return copy;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new DecoratingIterator(iterable.iterator()) {
+ @Override
+ public TYPE computeNext() {
+ return fromIterator.next();
+ }
+ };
+ }
+
+ /**
+ * @return a FluentIterable from a given iterable. Calls the LazyFluentIterable constructor.
+ */
+ public static final FluentIterable from(Iterable iterable) {
+ return new LazyFluentIterable<>(iterable);
+ }
+
+}
diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java
new file mode 100644
index 000000000..19283152e
--- /dev/null
+++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java
@@ -0,0 +1,198 @@
+package com.iluwatar.fluentinterface.fluentiterable.simple;
+
+import com.iluwatar.fluentinterface.fluentiterable.FluentIterable;
+
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * This is a simple implementation of the FluentIterable interface. It evaluates all chained
+ * operations eagerly. This implementation would be costly to be utilized in real applications.
+ *
+ * @param the type of the objects the iteration is about
+ */
+public class SimpleFluentIterable implements FluentIterable {
+
+ private final Iterable iterable;
+
+ /**
+ * This constructor creates a copy of a given iterable's contents.
+ *
+ * @param iterable the iterable this interface copies to work on.
+ */
+ protected SimpleFluentIterable(Iterable iterable) {
+ this.iterable = iterable;
+ }
+
+ /**
+ * Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy
+ * the predicate.
+ *
+ * @param predicate the condition to test with for the filtering. If the test is negative, the
+ * tested object is removed by the iterator.
+ * @return the same FluentIterable with a filtered collection
+ */
+ @Override
+ public final FluentIterable filter(Predicate super TYPE> predicate) {
+ Iterator iterator = iterator();
+ while (iterator.hasNext()) {
+ TYPE nextElement = iterator.next();
+ if (!predicate.test(nextElement)) {
+ iterator.remove();
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Can be used to collect objects from the Iterable. Is a terminating operation.
+ *
+ * @return an option of the first object of the Iterable
+ */
+ @Override
+ public final Optional first() {
+ Iterator resultIterator = first(1).iterator();
+ return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
+ }
+
+ /**
+ * Can be used to collect objects from the Iterable. Is a terminating operation.
+ *
+ * @param count defines the number of objects to return
+ * @return the same FluentIterable with a collection decimated to a maximum of 'count' first
+ * objects.
+ */
+ @Override
+ public final FluentIterable first(int count) {
+ Iterator iterator = iterator();
+ int currentCount = 0;
+ while (iterator.hasNext()) {
+ iterator.next();
+ if (currentCount >= count) {
+ iterator.remove();
+ }
+ currentCount++;
+ }
+ return this;
+ }
+
+ /**
+ * Can be used to collect objects from the Iterable. Is a terminating operation.
+ *
+ * @return an option of the last object of the Iterable
+ */
+ @Override
+ public final Optional last() {
+ List list = last(1).asList();
+ if (list.isEmpty()) {
+ return Optional.empty();
+ }
+ return Optional.of(list.get(0));
+ }
+
+ /**
+ * Can be used to collect objects from the Iterable. Is a terminating operation.
+ *
+ * @param count defines the number of objects to return
+ * @return the same FluentIterable with a collection decimated to a maximum of 'count' last
+ * objects
+ */
+ @Override
+ public final FluentIterable last(int count) {
+ int remainingElementsCount = getRemainingElementsCount();
+ Iterator iterator = iterator();
+ int currentIndex = 0;
+ while (iterator.hasNext()) {
+ iterator.next();
+ if (currentIndex < remainingElementsCount - count) {
+ iterator.remove();
+ }
+ currentIndex++;
+ }
+
+ return this;
+ }
+
+ /**
+ * Transforms this FluentIterable into a new one containing objects of the type NEW_TYPE.
+ *
+ * @param function a function that transforms an instance of TYPE into an instance of NEW_TYPE
+ * @param the target type of the transformation
+ * @return a new FluentIterable of the new type
+ */
+ @Override
+ public final FluentIterable map(Function super TYPE, NEW_TYPE> function) {
+ List temporaryList = new ArrayList<>();
+ Iterator iterator = iterator();
+ while (iterator.hasNext()) {
+ temporaryList.add(function.apply(iterator.next()));
+ }
+ return from(temporaryList);
+ }
+
+ /**
+ * Collects all remaining objects of this Iterable into a list.
+ *
+ * @return a list with all remaining objects of this Iterable
+ */
+ @Override
+ public List asList() {
+ return toList(iterable.iterator());
+ }
+
+ /**
+ * @return a FluentIterable from a given iterable. Calls the SimpleFluentIterable constructor.
+ */
+ public static final FluentIterable from(Iterable iterable) {
+ return new SimpleFluentIterable<>(iterable);
+ }
+
+ public static final FluentIterable fromCopyOf(Iterable iterable) {
+ List copy = FluentIterable.copyToList(iterable);
+ return new SimpleFluentIterable<>(copy);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return iterable.iterator();
+ }
+
+ @Override
+ public void forEach(Consumer super TYPE> action) {
+ iterable.forEach(action);
+ }
+
+
+ @Override
+ public Spliterator spliterator() {
+ return iterable.spliterator();
+ }
+
+ /**
+ * @return the count of remaining objects of the current Iterable
+ */
+ public final int getRemainingElementsCount() {
+ int counter = 0;
+ Iterator iterator = iterator();
+ while (iterator.hasNext()) {
+ iterator.next();
+ counter++;
+ }
+ return counter;
+ }
+
+ /**
+ * Collects the remaining objects of the given iterator into a List.
+ *
+ * @return a new List with the remaining objects.
+ */
+ public static List toList(Iterator iterator) {
+ List copy = new ArrayList<>();
+ while (iterator.hasNext()) {
+ copy.add(iterator.next());
+ }
+ return copy;
+ }
+}
diff --git a/fluentinterface/src/test/java/com/iluwatar/fluentinterface/AppTest.java b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/AppTest.java
new file mode 100644
index 000000000..d0abb7bf1
--- /dev/null
+++ b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/AppTest.java
@@ -0,0 +1,12 @@
+package com.iluwatar.fluentinterface;
+
+import org.junit.Test;
+
+public class AppTest {
+
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
+}
diff --git a/naked-objects/pom.xml b/naked-objects/pom.xml
index 8cac48a09..c9387b58d 100644
--- a/naked-objects/pom.xml
+++ b/naked-objects/pom.xml
@@ -27,7 +27,7 @@
- 1.9.0-SNAPSHOT
+ 1.9.0
UTF-8
UTF-8
diff --git a/pom.xml b/pom.xml
index 68cfab646..2205c9220 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,6 @@
-
+
4.0.0
com.iluwatar
@@ -9,8 +10,8 @@
UTF-8
- 5.0.0.Final
- 1.8.2.RELEASE
+ 5.0.1.Final
+ 1.9.0.RELEASE
1.4.188
4.12
3.0
@@ -77,8 +78,9 @@
step-builder
layers
message-channel
+ fluentinterface
reactor
-
+
@@ -206,6 +208,30 @@
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 2.15
+
+
+ validate
+
+ check
+
+ validate
+
+ checkstyle.xml
+ UTF-8
+ false
+ false
+
+
+
+
diff --git a/update-ghpages.sh b/update-ghpages.sh
new file mode 100644
index 000000000..82486d5a4
--- /dev/null
+++ b/update-ghpages.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# Clone gh-pages
+git clone -b gh-pages "https://${GH_REF}" ghpagesclone
+cd ghpagesclone
+
+# Init and update submodule to latest
+git submodule update --init --recursive
+git submodule update --remote
+
+# Setup Git
+git config user.name "Travis-CI"
+git config user.email "travis@no.reply"
+
+# If there is a new version of the master branch
+if git status | grep patterns > /dev/null 2>&1
+then
+ # it should be committed
+ git add .
+ git commit -m ":sparkles: :up: Automagic Update via Travis-CI"
+ git push --quiet "https://${GH_TOKEN}:x-oauth-basic@${GH_REF}" gh-pages > /dev/null 2>&1
+fi