COLLECTIONS-213. Added IteratorIterable adaptor class.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1126836 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brent Worden 2011-05-24 02:46:02 +00:00
parent 07947bd69e
commit 0543f907c1
4 changed files with 170 additions and 0 deletions

View File

@ -41,6 +41,7 @@ import org.apache.commons.collections.iterators.FilterIterator;
import org.apache.commons.collections.iterators.FilterListIterator;
import org.apache.commons.collections.iterators.IteratorChain;
import org.apache.commons.collections.iterators.IteratorEnumeration;
import org.apache.commons.collections.iterators.IteratorIterable;
import org.apache.commons.collections.iterators.ListIteratorWrapper;
import org.apache.commons.collections.iterators.LoopingIterator;
import org.apache.commons.collections.iterators.LoopingListIterator;
@ -757,6 +758,20 @@ public class IteratorUtils {
return new IteratorEnumeration<E>(iterator);
}
/**
* Gets an iterable that wraps an iterator.
*
* @param iterator the iterator to use, not null
* @return a new, single use iterable
* @throws NullPointerException if iterator is null
*/
public static <E> Iterable<E> asIterable(Iterator<? extends E> iterator) {
if (iterator == null) {
throw new NullPointerException("Iterator must not be null");
}
return new IteratorIterable<E>(iterator);
}
/**
* Gets a list iterator based on a simple iterator.
* <p>

View File

@ -0,0 +1,72 @@
/*
* 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.collections.iterators;
import java.util.Iterator;
/**
* Adapter to make an {@link Iterator Iterator} instance appear to be an
* {@link Iterable Iterable} instance. Unlike normal iterable instance, the
* {@link #iterator()} method always returns the same iterator instance. This
* prohibits this iterator to be only usable for one iterative operation.
*
* @since Commons Collections 4.0
* @version $Revision: $ $Date: $
*/
public class IteratorIterable<E> implements Iterable<E> {
/**
* Factory method to create an {@link Iterator Iterator} from another
* iterator over objects of a different subtype.
*/
private static <E> Iterator<E> createTypesafeIterator(
final Iterator<? extends E> iterator) {
return new Iterator<E>() {
public boolean hasNext() {
return iterator.hasNext();
}
public E next() {
return iterator.next();
}
public void remove() {
iterator.remove();
}
};
}
/** the iterator being used. */
private final Iterator<E> iterator;
/**
* Constructs a new <code>IteratorIterable</code> that will use the given
* iterator.
*
* @param iterator the iterator to use.
*/
public IteratorIterable(Iterator<? extends E> iterator) {
super();
this.iterator = createTypesafeIterator(iterator);
}
/**
* Gets the iterator wrapped by this iterable.
*
* @return the iterator
*/
public Iterator<E> iterator() {
return iterator;
}
}

View File

@ -48,6 +48,35 @@ public class TestIteratorUtils extends BulkTest {
return BulkTest.makeSuite(TestIteratorUtils.class);
}
public void testAsIterable() {
List<Integer> list = new ArrayList<Integer>();
list.add(Integer.valueOf(0));
list.add(Integer.valueOf(1));
list.add(Integer.valueOf(2));
Iterator<Integer> iterator = list.iterator();
Iterable<Integer> iterable = IteratorUtils.asIterable(iterator);
int expected = 0;
for(Integer actual : iterable) {
assertEquals(expected, actual.intValue());
++expected;
}
// single use iterator
for(Integer actual : iterable) {
fail("should not be able to iterate twice");
}
}
public void testAsIterableNull() {
try {
IteratorUtils.asIterable(null);
fail("Expecting NullPointerException");
} catch (NullPointerException ex) {
// success
}
}
public void testToList() {
List<Object> list = new ArrayList<Object>();
list.add(new Integer(1));

View File

@ -0,0 +1,54 @@
/*
* 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.collections.iterators;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.Test;
import org.apache.commons.collections.BulkTest;
/**
* Tests for IteratorIterable.
*
* @version $Revision: $ $Date: $
*/
public class TestIteratorIterable extends BulkTest {
public static Test suite() {
return BulkTest.makeSuite(TestIteratorIterable.class);
}
public TestIteratorIterable(String name) {
super(name);
}
public void testIterator() {
List<Integer> list = new ArrayList<Integer>();
list.add(Integer.valueOf(0));
list.add(Integer.valueOf(1));
list.add(Integer.valueOf(2));
Iterator<Integer> iter = list.iterator();
Iterable<Number> iterable = new IteratorIterable<Number>(iter);
int expected = 0;
for (Number actual : iterable) {
assertEquals(expected, actual.intValue());
++expected;
}
}
}