#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.Iterator;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -18,7 +17,7 @@ import java.util.function.Predicate;
public interface FluentIterable<TYPE> extends Iterable<TYPE> { 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 * @param predicate the condition to test with for the filtering. If the test
* is negative, the tested object is removed by the iterator. * is negative, the tested object is removed by the iterator.
* @return a filtered FluentIterable * @return a filtered FluentIterable
@ -26,13 +25,8 @@ public interface FluentIterable<TYPE> extends Iterable<TYPE> {
FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate); FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate);
/** /**
* Uses the Iterable interface's forEach method to apply a given function * Returns an Optional containing the first element of this iterable if present,
* for each object of the iterator. This is a terminating operation. * else returns Optional.empty().
*/
void forEachDo(Consumer<? super TYPE> action);
/**
* Evaluates the iteration and returns the first element. This is a terminating operation.
* @return the first element after the iteration is evaluated * @return the first element after the iteration is evaluated
*/ */
Optional<TYPE> first(); Optional<TYPE> first();
@ -62,6 +56,11 @@ public interface FluentIterable<TYPE> extends Iterable<TYPE> {
* @return a new FluentIterable of the new type * @return a new FluentIterable of the new type
*/ */
<NEW_TYPE> FluentIterable<NEW_TYPE> map(Function<? super TYPE, NEW_TYPE> function); <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(); 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 * @return true if a next element is available
*/ */
@Override @Override
@ -32,22 +32,24 @@ public abstract class DecoratingIterator<TYPE> implements Iterator<TYPE> {
} }
/** /**
* Returns the next element of the iteration. This implementation caches it. * Returns the next element of the Iterable.
* If no next element is cached, it is computed. * @return the next element of the Iterable, or null if not present.
* @return the next element obf the iteration
*/ */
@Override @Override
public final TYPE next() { public final TYPE next() {
TYPE result = next; if (next == null) {
return fromIterator.next();
} else {
final TYPE result = next;
next = null; next = null;
result = (result == null ? fromIterator.next() : result);
return result; return result;
} }
}
/** /**
* Computes the next object of the iteration. Can be implemented to * Computes the next object of the Iterable. Can be implemented to
* realize custom behaviour for an iteration process. * realize custom behaviour for an iteration process. null is considered as end of data.
* @return * @return the next element of the Iterable.
*/ */
public abstract TYPE computeNext(); 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 * @param predicate the condition to test with for the filtering. If the test
* is negative, the tested object is removed by the iterator. * is negative, the tested object is removed by the iterator.
* @return a new FluentIterable object that decorates the source iterable * @return a new FluentIterable object that decorates the source iterable
@ -50,8 +50,7 @@ public class LazyFluentIterable<TYPE> implements FluentIterable<TYPE> {
return new DecoratingIterator<TYPE>(iterable.iterator()) { return new DecoratingIterator<TYPE>(iterable.iterator()) {
@Override @Override
public TYPE computeNext() { public TYPE computeNext() {
while(true) { while(fromIterator.hasNext()) {
if(fromIterator.hasNext()) {
TYPE candidate = fromIterator.next(); TYPE candidate = fromIterator.next();
if(!predicate.test(candidate)) { if(!predicate.test(candidate)) {
continue; continue;
@ -61,42 +60,23 @@ public class LazyFluentIterable<TYPE> implements FluentIterable<TYPE> {
return null; 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. * 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 @Override
public Optional<TYPE> first() { public Optional<TYPE> first() {
Optional result = Optional.empty(); Iterator<TYPE> resultIterator = first(1).iterator();
List<TYPE> list = first(1).asList(); return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
if(!list.isEmpty()) {
result = Optional.of(list.get(0));
}
return result;
} }
/** /**
* 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 * @param count defines the number of objects to return
* @return the same FluentIterable with a collection decimated to a maximum of 'count' first objects. * @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. * 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 @Override
public Optional<TYPE> last() { public Optional<TYPE> last() {
Optional result = Optional.empty(); Iterator<TYPE> resultIterator = last(1).iterator();
List<TYPE> list = last(1).asList(); return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
if(!list.isEmpty()) {
result = Optional.of(list.get(0));
}
return result;
} }
/** /**
* 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 * @param count defines the number of objects to return
* @return the same FluentIterable with a collection decimated to a maximum of 'count' last objects * @return the same FluentIterable with a collection decimated to a maximum of 'count' last objects
*/ */
@ -193,14 +170,12 @@ public class LazyFluentIterable<TYPE> implements FluentIterable<TYPE> {
Iterator<TYPE> oldTypeIterator = iterable.iterator(); Iterator<TYPE> oldTypeIterator = iterable.iterator();
@Override @Override
public NEW_TYPE computeNext() { public NEW_TYPE computeNext() {
while(true) { while(oldTypeIterator.hasNext()) {
if(oldTypeIterator.hasNext()) {
TYPE candidate = oldTypeIterator.next(); TYPE candidate = oldTypeIterator.next();
return function.apply(candidate); return function.apply(candidate);
} }
return null; 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 * @param predicate the condition to test with for the filtering. If the test
* is negative, the tested object is removed by the iterator. * is negative, the tested object is removed by the iterator.
* @return the same FluentIterable with a filtered collection * @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 * Can be used to collect objects from the Iterable. Is a terminating operation.
* for each object of the iterator. Is a terminating operation. * @return an option of the first object of the Iterable
* @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
*/ */
@Override @Override
public final Optional<TYPE> first() { public final Optional<TYPE> first() {
List<TYPE> list = first(1).asList(); Iterator<TYPE> resultIterator = first(1).iterator();
if(list.isEmpty()) { return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
return Optional.empty();
}
return Optional.of(list.get(0));
} }
/** /**
* 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 * @param count defines the number of objects to return
* @return the same FluentIterable with a collection decimated to a maximum of 'count' first objects. * @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. * Can be used to collect objects from the Iterable. Is a terminating operation.
* @return an option of the last object of the iteration * @return an option of the last object of the Iterable
*/ */
@Override @Override
public final Optional<TYPE> last() { 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 * @param count defines the number of objects to return
* @return the same FluentIterable with a collection decimated to a maximum of 'count' last objects * @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. * Collects all remaining objects of this Iterable into a list.
* @return a list with all remaining objects of this iteration * @return a list with all remaining objects of this Iterable
*/ */
@Override @Override
public List<TYPE> asList() { 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() { public final int getRemainingElementsCount() {
int counter = 0; 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. * @return a new List with the remaining objects.
*/ */
public static <TYPE> List<TYPE> toList(Iterator<TYPE> iterator) { public static <TYPE> List<TYPE> toList(Iterator<TYPE> iterator) {