Skip to content

Commit

Permalink
[COLLECTIONS-464] Add first version of a FluentIterable implementatio…
Browse files Browse the repository at this point in the history
…n, cleanup recently toString methods in IterableUtils, add SkippingIterator and additional methods to IteratorUtils and IterableUtils.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1681783 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
netomi committed May 26, 2015
1 parent 1918bb0 commit 27a9265
Show file tree
Hide file tree
Showing 7 changed files with 1,001 additions and 111 deletions.
4 changes: 2 additions & 2 deletions src/changes/changes.xml
Expand Up @@ -40,8 +40,8 @@
Added clarification to javadoc of "TreeBag#add(Object)" wrt null arguments.
</action>
<action issue="COLLECTIONS-427" dev="tn" type="add" due-to="Gonçalo Marques">
Added "toString(...)" methods to newly created "IteratorUtils" class to get a
string representation of an Iterable instance similar to "Arrays#toString(...)".
Added "toString(...)" methods to newly created "IterableUtils" and existing "IteratorUtils"
to get a string representation of an Iterable/Iterator instance similar to "Arrays#toString(...)".
</action>
<action issue="COLLECTIONS-427" dev="tn" type="fix">
Reverted performance improvement for "SetUniqueList#retainAll(Collection)"
Expand Down
23 changes: 7 additions & 16 deletions src/main/java/org/apache/commons/collections4/CollectionUtils.java
Expand Up @@ -1384,18 +1384,11 @@ public static <C> boolean addAll(final Collection<C> collection, final C[] eleme
* @return the object at the specified index
* @throws IndexOutOfBoundsException if the index is invalid
* @throws IllegalArgumentException if the object type is invalid
* @deprecated since 4.1, use {@code IteratorUtils.get(Iterator, int)} instead
*/
@Deprecated
public static <T> T get(final Iterator<T> iterator, final int index) {
int i = index;
checkIndexBounds(i);
while (iterator.hasNext()) {
i--;
if (i == -1) {
return iterator.next();
}
iterator.next();
}
throw new IndexOutOfBoundsException("Entry does not exist: " + i);
return IteratorUtils.get(iterator, index);
}

/**
Expand Down Expand Up @@ -1432,7 +1425,7 @@ public static <T> T get(final Enumeration<T> e, final int index) {
* @param index the index to check.
* @throws IndexOutOfBoundsException if the index is negative.
*/
private static void checkIndexBounds(final int index) {
static void checkIndexBounds(final int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
}
Expand All @@ -1449,13 +1442,11 @@ private static void checkIndexBounds(final int index) {
* @param <T> the type of object in the {@link Iterable}.
* @return the object at the specified index
* @throws IndexOutOfBoundsException if the index is invalid
* @deprecated since 4.1, use {@code IterableUtils.get(Iterable, int)} instead
*/
@Deprecated
public static <T> T get(final Iterable<T> iterable, final int index) {
checkIndexBounds(index);
if (iterable instanceof List<?>) {
return ((List<T>) iterable).get(index);
}
return get(iterable.iterator(), index);
return IterableUtils.get(iterable, index);
}

/**
Expand Down
181 changes: 181 additions & 0 deletions src/main/java/org/apache/commons/collections4/FluentIterable.java
@@ -0,0 +1,181 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4;

import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

/**
* A FluentIterable provides a powerful yet simple API for manipulating Iterable instances in a fluent manner.
* <p>
* A FluentIterable can be created either from an Iterable or from a set of elements.
* The following types of methods are provided:
* <ul>
* <li>fluent methods which return a new {@code FluentIterable} instance
* <li>conversion methods which copy the FluentIterable's contents into a new collection or array (e.g. toList())
* <li>utility methods which answer questions about the FluentIterable's contents (e.g. size(), anyMatch(Predicate))
* <li>
* </ul>
* <p>
* The following example outputs the first 3 even numbers in the range [1, 10] into a list:
* <pre>
* FluentIterable
* .of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
* .filter(new Predicate<Integer>() {
* public boolean evaluate(Integer number) {
* return number % 2 == 0;
* }
* )
* .transform(TransformerUtils.stringValueTransformer())
* .limit(3)
* .toList();
* </pre>
*
* @param <E> the element type
* @since 4.1
* @version $Id: $
*/
public class FluentIterable<E> implements Iterable<E> {

private final Iterable<E> iterable;

// Static factory methods
// ----------------------------------------------------------------------

public static <T> FluentIterable<T> of(T... elements) {
return of(Arrays.asList(elements));
}

public static <T> FluentIterable<T> of(Iterable<T> iterable) {
if (iterable == null) {
throw new NullPointerException("Iterable must not be null");
}
if (iterable instanceof FluentIterable<?>) {
return (FluentIterable<T>) iterable;
} else {
return new FluentIterable<T>(iterable);
}
}

// Constructor
// ----------------------------------------------------------------------

private FluentIterable(final Iterable<E> iterable) {
this.iterable = iterable;
}

// fluent construction methods
// ----------------------------------------------------------------------

public FluentIterable<E> append(final E... elements) {
return append(Arrays.asList(elements));
}

public FluentIterable<E> append(final Iterable<E> other) {
return of(IterableUtils.chainedIterable(iterable, other));
}

public FluentIterable<E> eval() {
return of(toList());
}

public FluentIterable<E> filter(final Predicate<E> predicate) {
return of(IterableUtils.filteredIterable(iterable, predicate));
}

public FluentIterable<E> limit(final int maxSize) {
return of(IterableUtils.boundedIterable(iterable, maxSize));
}

public FluentIterable<E> loop() {
return of(IterableUtils.loopingIterable(iterable));
}

public FluentIterable<E> skip(int elementsToSkip) {
return of(IterableUtils.skippingIterable(iterable, elementsToSkip));
}

public <O> FluentIterable<O> transform(final Transformer<? super E, ? extends O> transformer) {
return of(IterableUtils.transformedIterable(iterable, transformer));
}

public FluentIterable<E> unique() {
return of(IterableUtils.uniqueIterable(iterable));
}

// convenience methods
// ----------------------------------------------------------------------

public Iterator<E> iterator() {
return iterable.iterator();
}

public Enumeration<E> asEnumeration() {
return IteratorUtils.asEnumeration(iterator());
}

public boolean allMatch(final Predicate<? super E> predicate) {
return IterableUtils.matchesAll(iterable, predicate);
}

public boolean anyMatch(final Predicate<? super E> predicate) {
return IterableUtils.matchesAny(iterable, predicate);
}

public boolean isEmpty() {
return IterableUtils.isEmpty(iterable);
}

public boolean contains(final Object object) {
return IterableUtils.contains(iterable, object);
}

public E get(int position) {
return IterableUtils.get(iterable, position);
}

public int size() {
return IterableUtils.size(iterable);
}

public void copyInto(final Collection<? super E> collection) {
if (collection == null) {
throw new NullPointerException("Collection must not be null");
}

for (final E element : iterable) {
collection.add(element);
}
}

public E[] toArray(final Class<E> arrayClass) {
return IteratorUtils.toArray(iterator(), arrayClass);
}

public List<E> toList() {
return IteratorUtils.toList(iterator());
}

@Override
public String toString() {
return IterableUtils.toString(iterable);
}

}

0 comments on commit 27a9265

Please sign in to comment.