#184 Fluent interface pattern, documentation changed, collecting operations optimized

This commit is contained in:
Hannes Pernpeintner 2015-09-02 17:21:20 +02:00
parent ded21b70ac
commit a90fcc2391
4 changed files with 56 additions and 93 deletions

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@ -18,7 +17,7 @@ import java.util.function.Predicate;
public interface FluentIterable<TYPE> extends Iterable<TYPE> {
/**
* Filters the iteration with the given predicate.
* 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
@ -26,13 +25,8 @@ public interface FluentIterable<TYPE> extends Iterable<TYPE> {
FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate);
/**
* Uses the Iterable interface's forEach method to apply a given function
* for each object of the iterator. This is a terminating operation.
*/
void forEachDo(Consumer<? super TYPE> action);
/**
* Evaluates the iteration and returns the first element. This is a terminating operation.
* 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<TYPE> first();
@ -62,6 +56,11 @@ public interface FluentIterable<TYPE> extends Iterable<TYPE> {
* @return a new FluentIterable of the new type
*/
<NEW_TYPE> FluentIterable<NEW_TYPE> map(Function<? super TYPE, NEW_TYPE> function);
/**
* Returns the contents of this Iterable as a List.
* @return a List representation of this Iterable
*/
List<TYPE> asList();
/**

View File

@ -22,7 +22,7 @@ public abstract class DecoratingIterator<TYPE> implements Iterator<TYPE> {
}
/**
* Precomputes and caches the next element of the iteration.
* 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
@ -32,22 +32,24 @@ public abstract class DecoratingIterator<TYPE> implements Iterator<TYPE> {
}
/**
* Returns the next element of the iteration. This implementation caches it.
* If no next element is cached, it is computed.
* @return the next element obf the iteration
* Returns the next element of the Iterable.
* @return the next element of the Iterable, or null if not present.
*/
@Override
public final TYPE next() {
TYPE result = next;
next = null;
result = (result == null ? fromIterator.next() : result);
return result;
if (next == null) {
return fromIterator.next();
} else {
final TYPE result = next;
next = null;
return result;
}
}
/**
* Computes the next object of the iteration. Can be implemented to
* realize custom behaviour for an iteration process.
* @return
* 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();
}

View File

@ -37,7 +37,7 @@ public class LazyFluentIterable<TYPE> implements FluentIterable<TYPE> {
}
/**
* Adds a filter operation to the operation chain and returns a new 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 new FluentIterable object that decorates the source iterable
@ -50,53 +50,33 @@ public class LazyFluentIterable<TYPE> implements FluentIterable<TYPE> {
return new DecoratingIterator<TYPE>(iterable.iterator()) {
@Override
public TYPE computeNext() {
while(true) {
if(fromIterator.hasNext()) {
TYPE candidate = fromIterator.next();
if(!predicate.test(candidate)) {
continue;
}
return candidate;
while(fromIterator.hasNext()) {
TYPE candidate = fromIterator.next();
if(!predicate.test(candidate)) {
continue;
}
return null;
return candidate;
}
return null;
}
};
}
};
}
/**
* Uses the Iterable interface's forEach method to apply a given function
* for each object of the iterator. Is a terminating operation.
* @param action the action for each object
*/
@Override
public void forEachDo(Consumer<? super TYPE> action) {
Iterator<TYPE> newIterator = iterable.iterator();
while(newIterator.hasNext()) {
action.accept(newIterator.next());
}
}
/**
* Can be used to collect objects from the iteration. Is a terminating operation.
* @return an option of the first object of the iteration
* @return an Optional containing the first object of this Iterable
*/
@Override
public Optional<TYPE> first() {
Optional result = Optional.empty();
List<TYPE> list = first(1).asList();
if(!list.isEmpty()) {
result = Optional.of(list.get(0));
}
return result;
Iterator<TYPE> resultIterator = first(1).iterator();
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
}
/**
* Can be used to collect objects from the iteration. Is a terminating operation.
* 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.
*/
@ -126,21 +106,18 @@ public class LazyFluentIterable<TYPE> implements FluentIterable<TYPE> {
/**
* Can be used to collect objects from the iteration. Is a terminating operation.
* @return an option of the last object of the iteration
* @return an Optional containing the last object of this Iterable
*/
@Override
public Optional<TYPE> last() {
Optional result = Optional.empty();
List<TYPE> list = last(1).asList();
if(!list.isEmpty()) {
result = Optional.of(list.get(0));
}
return result;
Iterator<TYPE> resultIterator = last(1).iterator();
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
}
/**
* Can be used to collect objects from the iteration. Is a terminating operation.
* 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
*/
@ -193,13 +170,11 @@ public class LazyFluentIterable<TYPE> implements FluentIterable<TYPE> {
Iterator<TYPE> oldTypeIterator = iterable.iterator();
@Override
public NEW_TYPE computeNext() {
while(true) {
if(oldTypeIterator.hasNext()) {
TYPE candidate = oldTypeIterator.next();
return function.apply(candidate);
}
return null;
while(oldTypeIterator.hasNext()) {
TYPE candidate = oldTypeIterator.next();
return function.apply(candidate);
}
return null;
}
};
}

View File

@ -26,7 +26,7 @@ public class SimpleFluentIterable<TYPE> implements FluentIterable<TYPE> {
}
/**
* Iterates over all elements of this iterator and filters them.
* 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
@ -44,30 +44,17 @@ public class SimpleFluentIterable<TYPE> implements FluentIterable<TYPE> {
}
/**
* Uses the Iterable interface's forEach method to apply a given function
* for each object of the iterator. Is a terminating operation.
* @param action the action for each object
*/
@Override
public void forEachDo(Consumer<? super TYPE> action) {
iterable.forEach(action);
}
/**
* Can be used to collect objects from the iteration. Is a terminating operation.
* @return an option of the first object of the iteration
* 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<TYPE> first() {
List<TYPE> list = first(1).asList();
if(list.isEmpty()) {
return Optional.empty();
}
return Optional.of(list.get(0));
Iterator<TYPE> resultIterator = first(1).iterator();
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
}
/**
* Can be used to collect objects from the iteration. Is a terminating operation.
* 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.
*/
@ -86,8 +73,8 @@ public class SimpleFluentIterable<TYPE> implements FluentIterable<TYPE> {
}
/**
* Can be used to collect objects from the iteration. Is a terminating operation.
* @return an option of the last object of the iteration
* 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<TYPE> last() {
@ -99,7 +86,7 @@ public class SimpleFluentIterable<TYPE> implements FluentIterable<TYPE> {
}
/**
* Can be used to collect objects from the iteration. Is a terminating operation.
* 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
*/
@ -136,8 +123,8 @@ public class SimpleFluentIterable<TYPE> implements FluentIterable<TYPE> {
}
/**
* Collects all remaining objects of this iteration into a list.
* @return a list with all remaining objects of this iteration
* Collects all remaining objects of this Iterable into a list.
* @return a list with all remaining objects of this Iterable
*/
@Override
public List<TYPE> asList() {
@ -168,7 +155,7 @@ public class SimpleFluentIterable<TYPE> implements FluentIterable<TYPE> {
}
/**
* @return the count of remaining objects in the current iteration
* @return the count of remaining objects of the current Iterable
*/
public final int getRemainingElementsCount() {
int counter = 0;
@ -181,7 +168,7 @@ public class SimpleFluentIterable<TYPE> implements FluentIterable<TYPE> {
}
/**
* Collects the remaining objects of the given iterators iteration into an List.
* Collects the remaining objects of the given iterator into a List.
* @return a new List with the remaining objects.
*/
public static <TYPE> List<TYPE> toList(Iterator<TYPE> iterator) {