Skip to content

Commit a90fcc2

Browse files
committed
iluwatar#184 Fluent interface pattern, documentation changed, collecting operations optimized
1 parent ded21b7 commit a90fcc2

File tree

4 files changed

+56
-93
lines changed

4 files changed

+56
-93
lines changed

fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterable.java

+8-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.util.Iterator;
55
import java.util.List;
66
import java.util.Optional;
7-
import java.util.function.Consumer;
87
import java.util.function.Function;
98
import java.util.function.Predicate;
109

@@ -18,21 +17,16 @@
1817
public interface FluentIterable<TYPE> extends Iterable<TYPE> {
1918

2019
/**
21-
* Filters the iteration with the given predicate.
20+
* Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy the predicate.
2221
* @param predicate the condition to test with for the filtering. If the test
2322
* is negative, the tested object is removed by the iterator.
2423
* @return a filtered FluentIterable
2524
*/
2625
FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate);
2726

2827
/**
29-
* Uses the Iterable interface's forEach method to apply a given function
30-
* for each object of the iterator. This is a terminating operation.
31-
*/
32-
void forEachDo(Consumer<? super TYPE> action);
33-
34-
/**
35-
* Evaluates the iteration and returns the first element. This is a terminating operation.
28+
* Returns an Optional containing the first element of this iterable if present,
29+
* else returns Optional.empty().
3630
* @return the first element after the iteration is evaluated
3731
*/
3832
Optional<TYPE> first();
@@ -62,6 +56,11 @@ public interface FluentIterable<TYPE> extends Iterable<TYPE> {
6256
* @return a new FluentIterable of the new type
6357
*/
6458
<NEW_TYPE> FluentIterable<NEW_TYPE> map(Function<? super TYPE, NEW_TYPE> function);
59+
60+
/**
61+
* Returns the contents of this Iterable as a List.
62+
* @return a List representation of this Iterable
63+
*/
6564
List<TYPE> asList();
6665

6766
/**

fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java

+13-11
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public DecoratingIterator(Iterator<TYPE> fromIterator) {
2222
}
2323

2424
/**
25-
* Precomputes and caches the next element of the iteration.
25+
* Precomputes and saves the next element of the Iterable. null is considered as end of data.
2626
* @return true if a next element is available
2727
*/
2828
@Override
@@ -32,22 +32,24 @@ public final boolean hasNext() {
3232
}
3333

3434
/**
35-
* Returns the next element of the iteration. This implementation caches it.
36-
* If no next element is cached, it is computed.
37-
* @return the next element obf the iteration
35+
* Returns the next element of the Iterable.
36+
* @return the next element of the Iterable, or null if not present.
3837
*/
3938
@Override
4039
public final TYPE next() {
41-
TYPE result = next;
42-
next = null;
43-
result = (result == null ? fromIterator.next() : result);
44-
return result;
40+
if (next == null) {
41+
return fromIterator.next();
42+
} else {
43+
final TYPE result = next;
44+
next = null;
45+
return result;
46+
}
4547
}
4648

4749
/**
48-
* Computes the next object of the iteration. Can be implemented to
49-
* realize custom behaviour for an iteration process.
50-
* @return
50+
* Computes the next object of the Iterable. Can be implemented to
51+
* realize custom behaviour for an iteration process. null is considered as end of data.
52+
* @return the next element of the Iterable.
5153
*/
5254
public abstract TYPE computeNext();
5355
}

fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java

+22-47
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ protected LazyFluentIterable() {
3737
}
3838

3939
/**
40-
* Adds a filter operation to the operation chain and returns a new iterable.
40+
* Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy the predicate.
4141
* @param predicate the condition to test with for the filtering. If the test
4242
* is negative, the tested object is removed by the iterator.
4343
* @return a new FluentIterable object that decorates the source iterable
@@ -50,53 +50,33 @@ public Iterator<TYPE> iterator() {
5050
return new DecoratingIterator<TYPE>(iterable.iterator()) {
5151
@Override
5252
public TYPE computeNext() {
53-
while(true) {
54-
if(fromIterator.hasNext()) {
55-
TYPE candidate = fromIterator.next();
56-
if(!predicate.test(candidate)) {
57-
continue;
58-
}
59-
return candidate;
53+
while(fromIterator.hasNext()) {
54+
TYPE candidate = fromIterator.next();
55+
if(!predicate.test(candidate)) {
56+
continue;
6057
}
61-
62-
return null;
58+
return candidate;
6359
}
60+
61+
return null;
6462
}
6563
};
6664
}
6765
};
6866
}
6967

70-
/**
71-
* Uses the Iterable interface's forEach method to apply a given function
72-
* for each object of the iterator. Is a terminating operation.
73-
* @param action the action for each object
74-
*/
75-
@Override
76-
public void forEachDo(Consumer<? super TYPE> action) {
77-
Iterator<TYPE> newIterator = iterable.iterator();
78-
while(newIterator.hasNext()) {
79-
action.accept(newIterator.next());
80-
}
81-
}
82-
8368
/**
8469
* Can be used to collect objects from the iteration. Is a terminating operation.
85-
* @return an option of the first object of the iteration
70+
* @return an Optional containing the first object of this Iterable
8671
*/
8772
@Override
8873
public Optional<TYPE> first() {
89-
Optional result = Optional.empty();
90-
List<TYPE> list = first(1).asList();
91-
if(!list.isEmpty()) {
92-
result = Optional.of(list.get(0));
93-
}
94-
95-
return result;
74+
Iterator<TYPE> resultIterator = first(1).iterator();
75+
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
9676
}
9777

9878
/**
99-
* Can be used to collect objects from the iteration. Is a terminating operation.
79+
* Can be used to collect objects from the iteration.
10080
* @param count defines the number of objects to return
10181
* @return the same FluentIterable with a collection decimated to a maximum of 'count' first objects.
10282
*/
@@ -126,21 +106,18 @@ public TYPE computeNext() {
126106

127107
/**
128108
* Can be used to collect objects from the iteration. Is a terminating operation.
129-
* @return an option of the last object of the iteration
109+
* @return an Optional containing the last object of this Iterable
130110
*/
131111
@Override
132112
public Optional<TYPE> last() {
133-
Optional result = Optional.empty();
134-
List<TYPE> list = last(1).asList();
135-
if(!list.isEmpty()) {
136-
result = Optional.of(list.get(0));
137-
}
138-
139-
return result;
113+
Iterator<TYPE> resultIterator = last(1).iterator();
114+
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
140115
}
141116

142117
/**
143-
* Can be used to collect objects from the iteration. Is a terminating operation.
118+
* Can be used to collect objects from the Iterable. Is a terminating operation.
119+
* This operation is memory intensive, because the contents of this Iterable
120+
* are collected into a List, when the next object is requested.
144121
* @param count defines the number of objects to return
145122
* @return the same FluentIterable with a collection decimated to a maximum of 'count' last objects
146123
*/
@@ -193,13 +170,11 @@ public Iterator<NEW_TYPE> iterator() {
193170
Iterator<TYPE> oldTypeIterator = iterable.iterator();
194171
@Override
195172
public NEW_TYPE computeNext() {
196-
while(true) {
197-
if(oldTypeIterator.hasNext()) {
198-
TYPE candidate = oldTypeIterator.next();
199-
return function.apply(candidate);
200-
}
201-
return null;
173+
while(oldTypeIterator.hasNext()) {
174+
TYPE candidate = oldTypeIterator.next();
175+
return function.apply(candidate);
202176
}
177+
return null;
203178
}
204179
};
205180
}

fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java

+13-26
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected SimpleFluentIterable(Iterable<TYPE> iterable) {
2626
}
2727

2828
/**
29-
* Iterates over all elements of this iterator and filters them.
29+
* Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy the predicate.
3030
* @param predicate the condition to test with for the filtering. If the test
3131
* is negative, the tested object is removed by the iterator.
3232
* @return the same FluentIterable with a filtered collection
@@ -44,30 +44,17 @@ public final FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate) {
4444
}
4545

4646
/**
47-
* Uses the Iterable interface's forEach method to apply a given function
48-
* for each object of the iterator. Is a terminating operation.
49-
* @param action the action for each object
50-
*/
51-
@Override
52-
public void forEachDo(Consumer<? super TYPE> action) {
53-
iterable.forEach(action);
54-
}
55-
56-
/**
57-
* Can be used to collect objects from the iteration. Is a terminating operation.
58-
* @return an option of the first object of the iteration
47+
* Can be used to collect objects from the Iterable. Is a terminating operation.
48+
* @return an option of the first object of the Iterable
5949
*/
6050
@Override
6151
public final Optional<TYPE> first() {
62-
List<TYPE> list = first(1).asList();
63-
if(list.isEmpty()) {
64-
return Optional.empty();
65-
}
66-
return Optional.of(list.get(0));
52+
Iterator<TYPE> resultIterator = first(1).iterator();
53+
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
6754
}
6855

6956
/**
70-
* Can be used to collect objects from the iteration. Is a terminating operation.
57+
* Can be used to collect objects from the Iterable. Is a terminating operation.
7158
* @param count defines the number of objects to return
7259
* @return the same FluentIterable with a collection decimated to a maximum of 'count' first objects.
7360
*/
@@ -86,8 +73,8 @@ public final FluentIterable<TYPE> first(int count) {
8673
}
8774

8875
/**
89-
* Can be used to collect objects from the iteration. Is a terminating operation.
90-
* @return an option of the last object of the iteration
76+
* Can be used to collect objects from the Iterable. Is a terminating operation.
77+
* @return an option of the last object of the Iterable
9178
*/
9279
@Override
9380
public final Optional<TYPE> last() {
@@ -99,7 +86,7 @@ public final Optional<TYPE> last() {
9986
}
10087

10188
/**
102-
* Can be used to collect objects from the iteration. Is a terminating operation.
89+
* Can be used to collect objects from the Iterable. Is a terminating operation.
10390
* @param count defines the number of objects to return
10491
* @return the same FluentIterable with a collection decimated to a maximum of 'count' last objects
10592
*/
@@ -136,8 +123,8 @@ public final <NEW_TYPE> FluentIterable<NEW_TYPE> map(Function<? super TYPE, NEW_
136123
}
137124

138125
/**
139-
* Collects all remaining objects of this iteration into a list.
140-
* @return a list with all remaining objects of this iteration
126+
* Collects all remaining objects of this Iterable into a list.
127+
* @return a list with all remaining objects of this Iterable
141128
*/
142129
@Override
143130
public List<TYPE> asList() {
@@ -168,7 +155,7 @@ public Spliterator<TYPE> spliterator() {
168155
}
169156

170157
/**
171-
* @return the count of remaining objects in the current iteration
158+
* @return the count of remaining objects of the current Iterable
172159
*/
173160
public final int getRemainingElementsCount() {
174161
int counter = 0;
@@ -181,7 +168,7 @@ public final int getRemainingElementsCount() {
181168
}
182169

183170
/**
184-
* Collects the remaining objects of the given iterators iteration into an List.
171+
* Collects the remaining objects of the given iterator into a List.
185172
* @return a new List with the remaining objects.
186173
*/
187174
public static <TYPE> List<TYPE> toList(Iterator<TYPE> iterator) {

0 commit comments

Comments
 (0)