blob: da0c1d1e8b8574d700759fbeabb7aa30e2c47e4f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2010 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.common.utility.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;
import java.util.RandomAccess;
import java.util.TreeSet;
import java.util.Vector;
import org.eclipse.jpt.common.utility.internal.iterables.ArrayIterable;
import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator;
import org.eclipse.jpt.common.utility.internal.iterators.ArrayListIterator;
import org.eclipse.jpt.common.utility.internal.iterators.SingleElementIterator;
import org.eclipse.jpt.common.utility.internal.iterators.SingleElementListIterator;
import org.eclipse.jpt.common.utility.internal.iterators.SuperIteratorWrapper;
/**
* {@link Collection}-related utility methods.
*/
public final class CollectionTools {
// ********** add all **********
/**
* Add all the elements returned by the specified iterable
* to the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.addAll(Iterable iterable)</code>
*/
public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable) {
return addAll(collection, iterable.iterator());
}
/**
* Add all the elements returned by the specified iterable
* to the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.addAll(Iterable iterable)</code>
*/
public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable, int size) {
return addAll(collection, iterable.iterator(), size);
}
/**
* Add all the elements returned by the specified iterator
* to the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.addAll(Iterator iterator)</code>
*/
public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator) {
return iterator.hasNext() ? addAll_(collection, iterator) : false;
}
/**
* assume the iterator is not empty
*/
private static <E> boolean addAll_(Collection<? super E> collection, Iterator<? extends E> iterator) {
boolean modified = false;
while (iterator.hasNext()) {
modified |= collection.add(iterator.next());
}
return modified;
}
/**
* Add all the elements returned by the specified iterator
* to the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.addAll(Iterator iterator)</code>
*/
public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator, int size) {
return iterator.hasNext() ? collection.addAll(list(iterator, size)) : false;
}
/**
* Add all the elements in the specified array
* to the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.addAll(Object[] array)</code>
*/
public static <E> boolean addAll(Collection<? super E> collection, E... array) {
return (array.length == 0) ? false : addAll_(collection, array);
}
/**
* assume the array is not empty
*/
private static <E> boolean addAll_(Collection<? super E> collection, E... array) {
boolean modified = false;
for (E element : array) {
modified |= collection.add(element);
}
return modified;
}
/**
* Add all the elements returned by the specified iterable
* to the specified list at the specified index.
* Return whether the list changed as a result.
* <p>
* <code>List.addAll(Iterable iterable)</code>
*/
public static <E> boolean addAll(List<? super E> list, int index, Iterable<E> iterable) {
return addAll(list, index, iterable.iterator());
}
/**
* Add all the elements returned by the specified iterable
* to the specified list at the specified index.
* Return whether the list changed as a result.
* <p>
* <code>List.addAll(Iterable iterable)</code>
*/
public static <E> boolean addAll(List<? super E> list, int index, Iterable<E> iterable, int size) {
return addAll(list, index, iterable.iterator(), size);
}
/**
* Add all the elements returned by the specified iterator
* to the specified list at the specified index.
* Return whether the list changed as a result.
* <p>
* <code>List.addAll(Iterator iterator)</code>
*/
public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator) {
return iterator.hasNext() ? list.addAll(index, list(iterator)) : false;
}
/**
* Add all the elements returned by the specified iterator
* to the specified list at the specified index.
* Return whether the list changed as a result.
* <p>
* <code>List.addAll(Iterator iterator)</code>
*/
public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator, int size) {
return iterator.hasNext() ? list.addAll(index, list(iterator, size)) : false;
}
/**
* Add all the elements in the specified array
* to the specified list at the specified index.
* Return whether the list changed as a result.
* <p>
* <code>List.addAll(Object[] array)</code>
*/
public static <E> boolean addAll(List<? super E> list, int index, E... array) {
return (array.length == 0) ? false : list.addAll(index, Arrays.asList(array));
}
// ********** bag **********
/**
* Return a bag corresponding to the specified enumeration.
* <p>
* <code>HashBag(Enumeration enumeration)</code>
*/
public static <E> HashBag<E> bag(Enumeration<? extends E> enumeration) {
return bag(enumeration, new HashBag<E>());
}
/**
* Return a bag corresponding to the specified enumeration.
* The specified enumeration size is a performance hint.
* <p>
* <code>HashBag(Enumeration enumeration)</code>
*/
public static <E> HashBag<E> bag(Enumeration<? extends E> enumeration, int enumerationSize) {
return bag(enumeration, new HashBag<E>(enumerationSize));
}
private static <E> HashBag<E> bag(Enumeration<? extends E> enumeration, HashBag<E> bag) {
while (enumeration.hasMoreElements()) {
bag.add(enumeration.nextElement());
}
return bag;
}
/**
* Return a bag corresponding to the specified iterable.
* <p>
* <code>HashBag(Iterable iterable)</code>
*/
public static <E> HashBag<E> bag(Iterable<? extends E> iterable) {
return bag(iterable.iterator());
}
/**
* Return a bag corresponding to the specified iterable.
* The specified iterable size is a performance hint.
* <p>
* <code>HashBag(Iterable iterable)</code>
*/
public static <E> HashBag<E> bag(Iterable<? extends E> iterable, int iterableSize) {
return bag(iterable.iterator(), iterableSize);
}
/**
* Return a bag corresponding to the specified iterator.
* <p>
* <code>HashBag(Iterator iterator)</code>
*/
public static <E> HashBag<E> bag(Iterator<? extends E> iterator) {
return bag(iterator, new HashBag<E>());
}
/**
* Return a bag corresponding to the specified iterator.
* The specified iterator size is a performance hint.
* <p>
* <code>HashBag(Iterator iterator)</code>
*/
public static <E> HashBag<E> bag(Iterator<? extends E> iterator, int iteratorSize) {
return bag(iterator, new HashBag<E>(iteratorSize));
}
private static <E> HashBag<E> bag(Iterator<? extends E> iterator, HashBag<E> bag) {
while (iterator.hasNext()) {
bag.add(iterator.next());
}
return bag;
}
/**
* Return a bag corresponding to the specified array.
* <p>
* <code>HashBag(Object[] array)</code>
*/
public static <E> HashBag<E> bag(E... array) {
int len = array.length;
HashBag<E> bag = new HashBag<E>(len);
for (E item : array) {
bag.add(item);
}
return bag;
}
// ********** collection **********
/**
* Return a collection corresponding to the specified enumeration.
*/
public static <E> HashBag<E> collection(Enumeration<? extends E> enumeration) {
return bag(enumeration);
}
/**
* Return a collection corresponding to the specified enumeration.
* The specified enumeration size is a performance hint.
*/
public static <E> HashBag<E> collection(Enumeration<? extends E> enumeration, int enumerationSize) {
return bag(enumeration, enumerationSize);
}
/**
* Return a collection corresponding to the specified iterable.
*/
public static <E> HashBag<E> collection(Iterable<? extends E> iterable) {
return collection(iterable.iterator());
}
/**
* Return a collection corresponding to the specified iterable.
* The specified iterable size is a performance hint.
*/
public static <E> HashBag<E> collection(Iterable<? extends E> iterable, int iterableSize) {
return collection(iterable.iterator(), iterableSize);
}
/**
* Return a collection corresponding to the specified iterator.
*/
public static <E> HashBag<E> collection(Iterator<? extends E> iterator) {
return bag(iterator);
}
/**
* Return a collection corresponding to the specified iterator.
* The specified iterator size is a performance hint.
*/
public static <E> HashBag<E> collection(Iterator<? extends E> iterator, int iteratorSize) {
return bag(iterator, iteratorSize);
}
/**
* Return a collection corresponding to the specified array.
*/
public static <E> HashBag<E> collection(E... array) {
return bag(array);
}
// ********** contains **********
/**
* Return whether the specified enumeration contains the
* specified element.
* <p>
* <code>Enumeration.contains(Object o)</code>
*/
public static boolean contains(Enumeration<?> enumeration, Object value) {
if (value == null) {
while (enumeration.hasMoreElements()) {
if (enumeration.nextElement() == null) {
return true;
}
}
} else {
while (enumeration.hasMoreElements()) {
if (value.equals(enumeration.nextElement())) {
return true;
}
}
}
return false;
}
/**
* Return whether the specified iterable contains the
* specified element.
* <p>
* <code>Iterable.contains(Object o)</code>
*/
public static boolean contains(Iterable<?> iterable, Object value) {
return contains(iterable.iterator(), value);
}
/**
* Return whether the specified iterator contains the
* specified element.
* <p>
* <code>Iterator.contains(Object o)</code>
*/
public static boolean contains(Iterator<?> iterator, Object value) {
if (value == null) {
while (iterator.hasNext()) {
if (iterator.next() == null) {
return true;
}
}
} else {
while (iterator.hasNext()) {
if (value.equals(iterator.next())) {
return true;
}
}
}
return false;
}
// ********** contains all **********
/**
* Return whether the specified collection contains all of the
* elements in the specified iterable.
* <p>
* <code>Collection.containsAll(Iterable iterable)</code>
*/
public static boolean containsAll(Collection<?> collection, Iterable<?> iterable) {
return containsAll(collection, iterable.iterator());
}
/**
* Return whether the specified collection contains all of the
* elements in the specified iterator.
* <p>
* <code>Collection.containsAll(Iterator iterator)</code>
*/
public static boolean containsAll(Collection<?> collection, Iterator<?> iterator) {
while (iterator.hasNext()) {
if ( ! collection.contains(iterator.next())) {
return false;
}
}
return true;
}
/**
* Return whether the specified collection contains all of the
* elements in the specified array.
* <p>
* <code>Collection.containsAll(Object[] array)</code>
*/
public static boolean containsAll(Collection<?> collection, Object... array) {
for (int i = array.length; i-- > 0; ) {
if ( ! collection.contains(array[i])) {
return false;
}
}
return true;
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified collection.
* <p>
* <code>Iterable.containsAll(Collection collection)</code>
*/
public static boolean containsAll(Iterable<?> iterable, Collection<?> collection) {
return containsAll(iterable.iterator(), collection);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified collection.
* The specified iterable size is a performance hint.
* <p>
* <code>Iterable.containsAll(Collection collection)</code>
*/
public static boolean containsAll(Iterable<?> iterable, int iterableSize, Collection<?> collection) {
return containsAll(iterable.iterator(), iterableSize, collection);
}
/**
* Return whether the specified iterable 1 contains all of the
* elements in the specified iterable 2.
* <p>
* <code>Iterable.containsAll(Iterable iterable)</code>
*/
public static boolean containsAll(Iterable<?> iterable1, Iterable<?> iterable2) {
return containsAll(iterable1.iterator(), iterable2.iterator());
}
/**
* Return whether the specified iterable 1 contains all of the
* elements in the specified iterable 2.
* The specified iterable 1 size is a performance hint.
* <p>
* <code>Iterable.containsAll(Iterable iterable)</code>
*/
public static boolean containsAll(Iterable<?> iterable1, int iterable1Size, Iterable<?> iterable2) {
return containsAll(iterable1.iterator(), iterable1Size, iterable2.iterator());
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified iterator.
* <p>
* <code>Iterable.containsAll(Iterator iterator)</code>
*/
public static boolean containsAll(Iterable<?> iterable, Iterator<?> iterator) {
return containsAll(iterable.iterator(), iterator);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified iterator.
* The specified iterable size is a performance hint.
* <p>
* <code>Iterable.containsAll(Iterator iterator)</code>
*/
public static boolean containsAll(Iterable<?> iterable, int iterableSize, Iterator<?> iterator) {
return containsAll(iterable.iterator(), iterableSize, iterator);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified array.
* <p>
* <code>Iterable.containsAll(Object[] array)</code>
*/
public static boolean containsAll(Iterable<?> iterable, Object... array) {
return containsAll(iterable.iterator(), array);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified array.
* The specified iterable size is a performance hint.
* <p>
* <code>Iterable.containsAll(Object[] array)</code>
*/
public static boolean containsAll(Iterable<?> iterable, int iterableSize, Object... array) {
return containsAll(iterable.iterator(), iterableSize, array);
}
/**
* Return whether the specified iterator contains all of the
* elements in the specified collection.
* <p>
* <code>Iterator.containsAll(Collection collection)</code>
*/
public static boolean containsAll(Iterator<?> iterator, Collection<?> collection) {
return set(iterator).containsAll(collection);
}
/**
* Return whether the specified iterator contains all of the
* elements in the specified collection.
* The specified iterator size is a performance hint.
* <p>
* <code>Iterator.containsAll(Collection collection)</code>
*/
public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Collection<?> collection) {
return set(iterator, iteratorSize).containsAll(collection);
}
/**
* Return whether the specified iterator contains all of the
* elements in the specified iterable.
* <p>
* <code>Iterator.containsAll(Iterable iterable)</code>
*/
public static boolean containsAll(Iterator<?> iterator, Iterable<?> iterable) {
return containsAll(set(iterator), iterable);
}
/**
* Return whether the specified iterator contains all of the
* elements in the specified iterable.
* The specified iterator size is a performance hint.
* <p>
* <code>Iterator.containsAll(Iterable iterable)</code>
*/
public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Iterable<?> iterable) {
return containsAll(set(iterator, iteratorSize), iterable);
}
/**
* Return whether the specified iterator 1 contains all of the
* elements in the specified iterator 2.
* <p>
* <code>Iterator.containsAll(Iterator iterator)</code>
*/
public static boolean containsAll(Iterator<?> iterator1, Iterator<?> iterator2) {
return containsAll(set(iterator1), iterator2);
}
/**
* Return whether the specified iterator 1 contains all of the
* elements in the specified iterator 2.
* The specified iterator 1 size is a performance hint.
* <p>
* <code>Iterator.containsAll(Iterator iterator)</code>
*/
public static boolean containsAll(Iterator<?> iterator1, int iterator1Size, Iterator<?> iterator2) {
return containsAll(set(iterator1, iterator1Size), iterator2);
}
/**
* Return whether the specified iterator contains all of the
* elements in the specified array.
* <p>
* <code>Iterator.containsAll(Object[] array)</code>
*/
public static boolean containsAll(Iterator<?> iterator, Object... array) {
return containsAll(set(iterator), array);
}
/**
* Return whether the specified iterator contains all of the
* elements in the specified array.
* The specified iterator size is a performance hint.
* <p>
* <code>Iterator.containsAll(Object[] array)</code>
*/
public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Object... array) {
return containsAll(set(iterator, iteratorSize), array);
}
// ********** diff **********
/**
* Return the index of the first elements in the specified
* lists that are different, beginning at the end.
* If the lists are identical, return -1.
* If the lists are different sizes, return the index of the
* last element in the longer list.
* Use the elements' {@link Object#equals(Object)} method to compare the
* elements.
* <p>
* <code>Collections.diffEnd(List list1, List list2)</code>
*/
public static int diffEnd(List<?> list1, List<?> list2) {
return ArrayTools.diffEnd(list1.toArray(), list2.toArray());
}
/**
* Return the range of elements in the specified
* arrays that are different.
* If the arrays are identical, return [size, -1].
* Use the elements' {@link Object#equals(Object)} method to compare the
* elements.
* <p>
* <code>Collections.diffRange(List list1, List list2)</code>
* @see #diffStart(List, List)
* @see #diffEnd(List, List)
*/
public static Range diffRange(List<?> list1, List<?> list2) {
return ArrayTools.diffRange(list1.toArray(), list2.toArray());
}
/**
* Return the index of the first elements in the specified
* lists that are different. If the lists are identical, return
* the size of the two lists (i.e. one past the last index).
* If the lists are different sizes and all the elements in
* the shorter list match their corresponding elements in
* the longer list, return the size of the shorter list
* (i.e. one past the last index of the shorter list).
* Use the elements' {@link Object#equals(Object)} method to compare the
* elements.
* <p>
* <code>Collections.diffStart(List list1, List list2)</code>
*/
public static int diffStart(List<?> list1, List<?> list2) {
return ArrayTools.diffStart(list1.toArray(), list2.toArray());
}
// ********** identity diff **********
/**
* Return the index of the first elements in the specified
* lists that are different, beginning at the end.
* If the lists are identical, return -1.
* If the lists are different sizes, return the index of the
* last element in the longer list.
* Use object identity to compare the elements.
* <p>
* <code>Collections.identityDiffEnd(List list1, List list2)</code>
*/
public static int identityDiffEnd(List<?> list1, List<?> list2) {
return ArrayTools.identityDiffEnd(list1.toArray(), list2.toArray());
}
/**
* Return the range of elements in the specified
* arrays that are different.
* If the arrays are identical, return [size, -1].
* Use object identity to compare the elements.
* <p>
* <code>Collections.identityDiffStart(List list1, List list2)</code>
* @see #identityDiffStart(List, List)
* @see #identityDiffEnd(List, List)
*/
public static Range identityDiffRange(List<?> list1, List<?> list2) {
return ArrayTools.identityDiffRange(list1.toArray(), list2.toArray());
}
/**
* Return the index of the first elements in the specified
* lists that are different. If the lists are identical, return
* the size of the two lists (i.e. one past the last index).
* If the lists are different sizes and all the elements in
* the shorter list match their corresponding elements in
* the longer list, return the size of the shorter list
* (i.e. one past the last index of the shorter list).
* Use object identity to compare the elements.
* <p>
* <code>Collections.identityDiffStart(List list1, List list2)</code>
*/
public static int identityDiffStart(List<?> list1, List<?> list2) {
return ArrayTools.identityDiffStart(list1.toArray(), list2.toArray());
}
// ********** elements are equal **********
/**
* Return whether the specified iterables do not return the same elements
* in the same order.
*/
public static boolean elementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) {
return elementsAreDifferent(iterable1.iterator(), iterable2.iterator());
}
/**
* Return whether the specified iterators do not return the same elements
* in the same order.
*/
public static boolean elementsAreDifferent(Iterator<?> iterator1, Iterator<?> iterator2) {
return ! elementsAreEqual(iterator1, iterator2);
}
/**
* Return whether the specified iterables return equal elements
* in the same order.
* <p>
* <code>Iterable.elementsAreEqual(Iterable iterable)</code>
*/
public static boolean elementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) {
return elementsAreEqual(iterable1.iterator(), iterable2.iterator());
}
/**
* Return whether the specified iterators return equal elements
* in the same order.
* <p>
* <code>Iterator.elementsAreEqual(Iterator iterator)</code>
*/
public static boolean elementsAreEqual(Iterator<?> iterator1, Iterator<?> iterator2) {
while (iterator1.hasNext() && iterator2.hasNext()) {
if (Tools.valuesAreDifferent(iterator1.next(), iterator2.next())) {
return false;
}
}
return ! (iterator1.hasNext() || iterator2.hasNext());
}
// ********** elements are identical **********
/**
* Return whether the specified iterables return the same elements.
* <p>
* <code>Iterable.identical(Iterable iterable)</code>
*/
public static boolean elementsAreIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {
return elementsAreIdentical(iterable1.iterator(), iterable2.iterator());
}
/**
* Return whether the specified iterators return the same elements.
* <p>
* <code>Iterator.identical(Iterator iterator)</code>
*/
public static boolean elementsAreIdentical(Iterator<?> iterator1, Iterator<?> iterator2) {
while (iterator1.hasNext() && iterator2.hasNext()) {
if (iterator1.next() != iterator2.next()) {
return false;
}
}
return ! (iterator1.hasNext() || iterator2.hasNext());
}
/**
* Return whether the specified iterables do <em>not</em> return the same
* elements.
* <p>
* <code>Iterable.notIdentical(Iterable iterable)</code>
*/
public static boolean elementsAreNotIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {
return elementsAreNotIdentical(iterable1.iterator(), iterable2.iterator());
}
/**
* Return whether the specified iterators do <em>not</em> return the same
* elements.
* <p>
* <code>Iterator.notIdentical(Iterator iterator)</code>
*/
public static boolean elementsAreNotIdentical(Iterator<?> iterator1, Iterator<?> iterator2) {
return ! elementsAreIdentical(iterator1, iterator2);
}
// ********** get **********
/**
* Return the element corresponding to the specified index
* in the specified iterable.
* <p>
* <code>Iterable.get(int index)</code>
*/
public static <E> E get(Iterable<? extends E> iterable, int index) {
return get(iterable.iterator(), index);
}
/**
* Return the element corresponding to the specified index
* in the specified iterator.
* <p>
* <code>Iterator.get(int index)</code>
*/
public static <E> E get(Iterator<? extends E> iterator, int index) {
int i = 0;
while (iterator.hasNext()) {
E next = iterator.next();
if (i++ == index) {
return next;
}
}
throw new IndexOutOfBoundsException(String.valueOf(index) + ':' + String.valueOf(i));
}
// ********** hash code **********
public static int hashCode(Iterable<?> iterable) {
if (iterable == null) {
return 0;
}
int hash = 1;
for (Object element : iterable) {
hash = 31 * hash + (element == null ? 0 : element.hashCode());
}
return hash;
}
// ********** index of **********
/**
* Return the index of the first occurrence of the
* specified element in the specified iterable;
* return -1 if there is no such index.
* <p>
* <code>Iterable.indexOf(Object o)</code>
*/
public static int indexOf(Iterable<?> iterable, Object value) {
return indexOf(iterable.iterator(), value);
}
/**
* Return the index of the first occurrence of the
* specified element in the specified iterator;
* return -1 if there is no such index.
* <p>
* <code>Iterator.indexOf(Object o)</code>
*/
public static int indexOf(Iterator<?> iterator, Object value) {
if (value == null) {
for (int i = 0; iterator.hasNext(); i++) {
if (iterator.next() == null) {
return i;
}
}
} else {
for (int i = 0; iterator.hasNext(); i++) {
if (value.equals(iterator.next())) {
return i;
}
}
}
return -1;
}
// ********** insertion index of **********
/**
* Return an index of where the specified comparable object
* can be inserted into the specified sorted list and still keep
* the list sorted. If the specified sorted list is an instance of
* {@link RandomAccess} return the <em>maximum</em> insertion index;
* otherwise return the <em>minimum</em> insertion index.
*/
public static <E extends Comparable<? super E>> int insertionIndexOf(List<E> sortedList, Comparable<E> value) {
if (sortedList instanceof RandomAccess) {
for (int i = sortedList.size(); i-- > 0; ) {
if (value.compareTo(sortedList.get(i)) >= 0) {
return i + 1;
}
}
return 0;
}
int i = 0;
for (E element : sortedList) {
if (value.compareTo(element) <= 0) {
return i;
}
i++;
}
return i;
}
/**
* Return an index of where the specified comparable object
* can be inserted into the specified sorted list and still keep
* the list sorted. If the specified sorted list is an instance of
* {@link RandomAccess} return the <em>maximum</em> insertion index;
* otherwise return the <em>minimum</em> insertion index.
*/
public static <E> int insertionIndexOf(List<E> sortedList, E value, Comparator<? super E> comparator) {
if (sortedList instanceof RandomAccess) {
for (int i = sortedList.size(); i-- > 0; ) {
if (comparator.compare(value, sortedList.get(i)) >= 0) {
return i + 1;
}
}
return 0;
}
int i = 0;
for (E element : sortedList) {
if (comparator.compare(value, element) <= 0) {
return i;
}
i++;
}
return i;
}
// ********** iterable/iterator **********
/**
* Return an iterable on the elements in the specified array.
* <p>
* <code>Arrays.iterable(Object[] array)</code>
*/
public static <E> Iterable<E> iterable(E... array) {
return new ArrayIterable<E>(array);
}
/**
* Return an iterator on the elements in the specified array.
* <p>
* <code>Arrays.iterator(Object[] array)</code>
*/
public static <E> Iterator<E> iterator(E... array) {
return new ArrayIterator<E>(array);
}
// ********** last **********
/**
* Return the specified iterable's last element.
* <p>
* <code>Iterable.last()</code>
*
* @exception java.util.NoSuchElementException iterable is empty.
*/
public static <E> E last(Iterable<E> iterable) {
return last(iterable.iterator());
}
/**
* Return the specified iterator's last element.
* <p>
* <code>Iterator.last()</code>
*
* @exception java.util.NoSuchElementException iterator is empty.
*/
public static <E> E last(Iterator<E> iterator) {
E last;
do {
last = iterator.next();
} while (iterator.hasNext());
return last;
}
// ********** last index of **********
/**
* Return the index of the last occurrence of the
* specified element in the specified iterable;
* return -1 if there is no such index.
* <p>
* <code>Iterable.lastIndexOf(Object o)
*/
public static int lastIndexOf(Iterable<?> iterable, Object value) {
return lastIndexOf(iterable.iterator(), value);
}
/**
* Return the index of the last occurrence of the
* specified element in the specified iterable;
* return -1 if there is no such index.
* The specified iterable size is a performance hint.
* <p>
* <code>Iterable.lastIndexOf(Object o)
*/
public static int lastIndexOf(Iterable<?> iterable, int iterableSize, Object value) {
return lastIndexOf(iterable.iterator(), iterableSize, value);
}
/**
* Return the index of the last occurrence of the
* specified element in the specified iterator;
* return -1 if there is no such index.
* <p>
* <code>Iterator.lastIndexOf(Object o)
*/
public static int lastIndexOf(Iterator<?> iterator, Object value) {
return iterator.hasNext() ? list(iterator).lastIndexOf(value) : -1;
}
/**
* Return the index of the last occurrence of the
* specified element in the specified iterator;
* return -1 if there is no such index.
* The specified iterator size is a performance hint.
* <p>
* <code>Iterator.lastIndexOf(Object o)
*/
public static int lastIndexOf(Iterator<?> iterator, int iteratorSize, Object value) {
return iterator.hasNext() ? list(iterator, iteratorSize).lastIndexOf(value) : -1;
}
// ********** list **********
/**
* Return a list corresponding to the specified iterable.
* <p>
* <code>Iterable.toList()</code>
*/
public static <E> ArrayList<E> list(Iterable<? extends E> iterable) {
return list(iterable.iterator());
}
/**
* Return a list corresponding to the specified iterable.
* The specified iterable size is a performance hint.
* <p>
* <code>Iterable.toList()</code>
*/
public static <E> ArrayList<E> list(Iterable<? extends E> iterable, int iterableSize) {
return list(iterable.iterator(), iterableSize);
}
/**
* Return a list corresponding to the specified iterator.
* <p>
* <code>Iterator.toList()</code>
*/
public static <E> ArrayList<E> list(Iterator<? extends E> iterator) {
return list(iterator, new ArrayList<E>());
}
/**
* Return a list corresponding to the specified iterator.
* The specified iterator size is a performance hint.
* <p>
* <code>Iterator.toList()</code>
*/
public static <E> ArrayList<E> list(Iterator<? extends E> iterator, int iteratorSize) {
return list(iterator, new ArrayList<E>(iteratorSize));
}
private static <E> ArrayList<E> list(Iterator<? extends E> iterator, ArrayList<E> list) {
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
/**
* Return a list corresponding to the specified array.
* Unlike {@link Arrays#asList(Object[])}, the list
* is modifiable and is not backed by the array.
*/
public static <E> ArrayList<E> list(E... array) {
return new ArrayList<E>(Arrays.asList(array));
}
/**
* Return a list iterator for the specified array.
* <p>
* <code>Arrays.listIterator(Object[] array)</code>
*/
public static <E> ListIterator<E> listIterator(E... array) {
return listIterator(array, 0);
}
/**
* Return a list iterator for the specified array
* starting at the specified position in the array.
* <p>
* <code>Arrays.listIterator(Object[] array, int index)</code>
*/
public static <E> ListIterator<E> listIterator(E[] array, int start) {
return listIterator(array, start, array.length - start);
}
/**
* Return a list iterator for the specified array
* starting at the specified position in the array.
* <p>
* <code>Arrays.listIterator(Object[] array, int index, int length)</code>
*/
public static <E> ListIterator<E> listIterator(E[] array, int start, int length) {
return new ArrayListIterator<E>(array, start, length);
}
// ********** move **********
/**
* Move an element from the specified source index to the specified target
* index. Return the altered list.
* <p>
* <code>List.move(int targetIndex, int sourceIndex)</code>
*/
public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex) {
return (targetIndex == sourceIndex) ? list : move_(list, targetIndex, sourceIndex);
}
/**
* assume targetIndex != sourceIndex
*/
private static <E> List<E> move_(List<E> list, int targetIndex, int sourceIndex) {
if (list instanceof RandomAccess) {
// move elements, leaving the list in place
E temp = list.get(sourceIndex);
if (targetIndex < sourceIndex) {
for (int i = sourceIndex; i-- > targetIndex; ) {
list.set(i + 1, list.get(i));
}
} else {
for (int i = sourceIndex; i < targetIndex; i++) {
list.set(i, list.get(i + 1));
}
}
list.set(targetIndex, temp);
} else {
// remove the element and re-add it at the target index
list.add(targetIndex, list.remove(sourceIndex));
}
return list;
}
/**
* Move elements from the specified source index to the specified target
* index. Return the altered list.
* <p>
* <code>List.move(int targetIndex, int sourceIndex, int length)</code>
*/
public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex, int length) {
if ((targetIndex == sourceIndex) || (length == 0)) {
return list;
}
if (length == 1) {
return move_(list, targetIndex, sourceIndex);
}
if (list instanceof RandomAccess) {
// move elements, leaving the list in place
ArrayList<E> temp = new ArrayList<E>(list.subList(sourceIndex, sourceIndex + length));
if (targetIndex < sourceIndex) {
for (int i = sourceIndex; i-- > targetIndex; ) {
list.set(i + length, list.get(i));
}
} else {
for (int i = sourceIndex; i < targetIndex; i++) {
list.set(i, list.get(i + length));
}
}
for (int i = 0; i < length; i++) {
list.set(targetIndex + i, temp.get(i));
}
} else {
// remove the elements and re-add them at the target index
list.addAll(targetIndex, removeElementsAtIndex(list, sourceIndex, length));
}
return list;
}
// ********** remove all **********
/**
* Remove all the elements returned by the specified iterable
* from the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.removeAll(Iterable iterable)</code>
*/
public static boolean removeAll(Collection<?> collection, Iterable<?> iterable) {
return removeAll(collection, iterable.iterator());
}
/**
* Remove all the elements returned by the specified iterable
* from the specified collection.
* Return whether the collection changed as a result.
* The specified iterable size is a performance hint.
* <p>
* <code>Collection.removeAll(Iterable iterable)</code>
*/
public static boolean removeAll(Collection<?> collection, Iterable<?> iterable, int iterableSize) {
return removeAll(collection, iterable.iterator(), iterableSize);
}
/**
* Remove all the elements returned by the specified iterator
* from the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.removeAll(Iterator iterator)</code>
*/
public static boolean removeAll(Collection<?> collection, Iterator<?> iterator) {
return iterator.hasNext() ? collection.removeAll(set(iterator)) : false;
}
/**
* Remove all the elements returned by the specified iterator
* from the specified collection.
* Return whether the collection changed as a result.
* The specified iterator size is a performance hint.
* <p>
* <code>Collection.removeAll(Iterator iterator)</code>
*/
public static boolean removeAll(Collection<?> collection, Iterator<?> iterator, int iteratorSize) {
return iterator.hasNext() ? collection.removeAll(set(iterator, iteratorSize)) : false;
}
/**
* Remove all the elements in the specified array
* from the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.removeAll(Object[] array)</code>
*/
public static boolean removeAll(Collection<?> collection, Object... array) {
return (array.length == 0) ? false : collection.removeAll(set(array));
}
// ********** remove all occurrences **********
/**
* Remove all occurrences of the specified element
* from the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.removeAllOccurrences(Object value)</code>
*/
public static boolean removeAllOccurrences(Collection<?> collection, Object value) {
boolean modified = false;
Iterator<?> stream = collection.iterator();
if (value == null) {
while (stream.hasNext()) {
if (stream.next() == null) {
stream.remove();
modified = true;
}
}
} else {
while (stream.hasNext()) {
if (value.equals(stream.next())) {
stream.remove();
modified = true;
}
}
}
return modified;
}
// ********** remove elements at index **********
/**
* Remove the elements at the specified index.
* Return the removed elements.
* <p>
* <code>List.remove(int index, int length)</code>
*/
public static <E> ArrayList<E> removeElementsAtIndex(List<E> list, int index, int length) {
List<E> subList = list.subList(index, index + length);
ArrayList<E> result = new ArrayList<E>(subList);
subList.clear();
return result;
}
// ********** remove duplicate elements **********
/**
* Remove any duplicate elements from the specified list,
* while maintaining the order.
* Return whether the list changed as a result.
*/
public static <E> boolean removeDuplicateElements(List<E> list) {
int size = list.size();
if ((size == 0) || (size == 1)) {
return false;
}
return removeDuplicateElements(list, size);
}
/**
* assume list is non-empty
*/
static <E> boolean removeDuplicateElements(List<E> list, int size) {
LinkedHashSet<E> temp = new LinkedHashSet<E>(size); // take advantage of hashed look-up
boolean modified = false;
for (E item : list) {
if ( ! temp.add(item)) {
modified = true; // duplicate item
}
}
if (modified) {
int i = 0;
for (E e : temp) {
list.set(i, e);
i++;
}
int tempSize = temp.size();
for (i = list.size(); i-- > tempSize; ) {
list.remove(i); // pull off the end
}
}
return modified;
}
// ********** retain all **********
/**
* Retain only the elements in the specified iterable
* in the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.retainAll(Iterable iterable)</code>
*/
public static boolean retainAll(Collection<?> collection, Iterable<?> iterable) {
return retainAll(collection, iterable.iterator());
}
/**
* Retain only the elements in the specified iterable
* in the specified collection.
* Return whether the collection changed as a result.
* The specified iterable size is a performance hint.
* <p>
* <code>Collection.retainAll(Iterable iterable)</code>
*/
public static boolean retainAll(Collection<?> collection, Iterable<?> iterable, int iterableSize) {
return retainAll(collection, iterable.iterator(), iterableSize);
}
/**
* Retain only the elements in the specified iterator
* in the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.retainAll(Iterator iterator)</code>
*/
public static boolean retainAll(Collection<?> collection, Iterator<?> iterator) {
if (iterator.hasNext()) {
return collection.retainAll(set(iterator));
}
if (collection.isEmpty()) {
return false;
}
collection.clear();
return true;
}
/**
* Retain only the elements in the specified iterator
* in the specified collection.
* Return whether the collection changed as a result.
* The specified iterator size is a performance hint.
* <p>
* <code>Collection.retainAll(Iterator iterator)</code>
*/
public static boolean retainAll(Collection<?> collection, Iterator<?> iterator, int iteratorSize) {
if (iterator.hasNext()) {
return collection.retainAll(set(iterator, iteratorSize));
}
if (collection.isEmpty()) {
return false;
}
collection.clear();
return true;
}
/**
* Retain only the elements in the specified array
* in the specified collection.
* Return whether the collection changed as a result.
* <p>
* <code>Collection.retainAll(Object[] array)</code>
*/
public static boolean retainAll(Collection<?> collection, Object... array) {
if (array.length > 0) {
return collection.retainAll(set(array));
}
if (collection.isEmpty()) {
return false;
}
collection.clear();
return true;
}
// ********** reverse list **********
/**
* Return a list with entries in reverse order from those
* returned by the specified iterable.
* <p>
* <code>Iterable.reverseList()</code>
*/
public static <E> ArrayList<E> reverseList(Iterable<? extends E> iterable) {
return reverseList(iterable.iterator());
}
/**
* Return a list with entries in reverse order from those
* returned by the specified iterable.
* The specified iterable size is a performance hint.
* <p>
* <code>Iterable.reverseList()</code>
*/
public static <E> ArrayList<E> reverseList(Iterable<? extends E> iterable, int iterableSize) {
return reverseList(iterable.iterator(), iterableSize);
}
/**
* Return a list with entries in reverse order from those
* returned by the specified iterator.
* <p>
* <code>Iterator.reverseList()</code>
*/
public static <E> ArrayList<E> reverseList(Iterator<? extends E> iterator) {
return (ArrayList<E>) reverse(list(iterator));
}
/**
* Return a list with entries in reverse order from those
* returned by the specified iterator.
* The specified iterator size is a performance hint.
* <p>
* <code>Iterator.reverseList()</code>
*/
public static <E> ArrayList<E> reverseList(Iterator<? extends E> iterator, int size) {
return (ArrayList<E>) reverse(list(iterator, size));
}
// ********** rotate **********
/**
* Return the list after it has been "rotated" by one position.
* <p>
* <code>List.rotate()</code>
*/
public static <E> List<E> rotate(List<E> list) {
return rotate(list, 1);
}
// ********** set **********
/**
* Return a set corresponding to the specified iterable.
* <p>
* <code>HashSet(Iterable iterable)</code>
*/
public static <E> HashSet<E> set(Iterable<? extends E> iterable) {
return set(iterable.iterator());
}
/**
* Return a set corresponding to the specified iterable.
* The specified iterable size is a performance hint.
* <p>
* <code>HashSet(Iterable iterable)</code>
*/
public static <E> HashSet<E> set(Iterable<? extends E> iterable, int iterableSize) {
return set(iterable.iterator(), iterableSize);
}
/**
* Return a set corresponding to the specified iterator.
* <p>
* <code>HashSet(Iterator iterator)</code>
*/
public static <E> HashSet<E> set(Iterator<? extends E> iterator) {
return set(iterator, new HashSet<E>());
}
/**
* Return a set corresponding to the specified iterator.
* The specified iterator size is a performance hint.
* <p>
* <code>HashSet(Iterator iterator)</code>
*/
public static <E> HashSet<E> set(Iterator<? extends E> iterator, int iteratorSize) {
return set(iterator, new HashSet<E>(iteratorSize));
}
private static <E> HashSet<E> set(Iterator<? extends E> iterator, HashSet<E> set) {
while (iterator.hasNext()) {
set.add(iterator.next());
}
return set;
}
/**
* Return a set corresponding to the specified array.
* <p>
* <code>HashSet(Object[] array)</code>
*/
public static <E> HashSet<E> set(E... array) {
HashSet<E> set = new HashSet<E>(array.length);
for (int i = array.length; i-- > 0;) {
set.add(array[i]);
}
return set;
}
// ********** singleton iterator **********
/**
* Return an iterator that returns only the single,
* specified object.
* <p>
* <code>Object.toIterator()</code>
*/
public static <E> Iterator<E> singletonIterator(E value) {
return new SingleElementIterator<E>(value);
}
/**
* Return a list iterator that returns only the single,
* specified object.
* <p>
* <code>Object.toListIterator()</code>
*/
public static <E> ListIterator<E> singletonListIterator(E value) {
return new SingleElementListIterator<E>(value);
}
// ********** size **********
/**
* Return the number of elements returned by the specified iterable.
* <p>
* <code>Iterable.size()</code>
*/
public static int size(Iterable<?> iterable) {
return size(iterable.iterator());
}
/**
* Return the number of elements returned by the specified iterator.
* <p>
* <code>Iterator.size()</code>
*/
public static int size(Iterator<?> iterator) {
int size = 0;
while (iterator.hasNext()) {
iterator.next();
size++;
}
return size;
}
/**
* Return whether the specified iterable is empty
* (Shortcuts the iterator rather than calculating the entire size)
*/
public static boolean isEmpty(Iterable<?> iterable) {
return isEmpty(iterable.iterator());
}
/**
* Return whether the specified iterator is empty
* (Shortcuts the iterator rather than calculating the entire size)
*/
public static boolean isEmpty(Iterator<?> iterator) {
return ! iterator.hasNext();
}
// ********** sort **********
/**
* Return an iterable containing the sorted elements of the specified iterable.
* <p>
* <code>Iterable.sort()</code>
*/
public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable) {
return sort(iterable, null);
}
/**
* Return an iterable containing the sorted elements of the specified iterable.
* The specified iterable size is a performance hint.
* <p>
* <code>Iterable.sort()</code>
*/
public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable, int iterableSize) {
return sort(iterable, null, iterableSize);
}
/**
* Return an iterable containing the sorted elements of the specified iterable.
* <p>
* <code>Iterable.sort(Comparator comparator)</code>
*/
public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator) {
return sort(list(iterable), comparator);
}
/**
* Return an iterable containing the sorted elements of the specified iterable.
* The specified iterable size is a performance hint.
* <p>
* <code>Iterable.sort(Comparator comparator)</code>
*/
public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator, int iterableSize) {
return sort(list(iterable, iterableSize), comparator);
}
/**
* Return the iterator after it has been "sorted".
* <p>
* <code>Iterator.sort()</code>
*/
public static <E extends Comparable<? super E>> ListIterator<E> sort(Iterator<? extends E> iterator) {
return sort(iterator, null);
}
/**
* Return the iterator after it has been "sorted".
* The specified iterator size is a performance hint.
* <p>
* <code>Iterator.sort()</code>
*/
public static <E extends Comparable<? super E>> ListIterator<E> sort(Iterator<? extends E> iterator, int iteratorSize) {
return sort(iterator, null, iteratorSize);
}
/**
* Return the iterator after it has been "sorted".
* <p>
* <code>Iterator.sort(Comparator comparator)</code>
*/
public static <E> ListIterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator) {
return sort(list(iterator), comparator).listIterator();
}
/**
* Return the iterator after it has been "sorted".
* The specified iterator size is a performance hint.
* <p>
* <code>Iterator.sort(Comparator comparator)</code>
*/
public static <E> ListIterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator, int iteratorSize) {
return sort(list(iterator, iteratorSize), comparator).listIterator();
}
// ********** sorted set **********
/**
* Return a sorted set corresponding to the specified iterable.
* <p>
* <code>TreeSet(Iterable iterable)</code>
*/
public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable) {
return sortedSet(iterable.iterator());
}
/**
* Return a sorted set corresponding to the specified iterable.
* The specified iterable size is a performance hint.
* <p>
* <code>TreeSet(Iterable iterable)</code>
*/
public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable, int iterableSize) {
return sortedSet(iterable.iterator(), iterableSize);
}
/**
* Return a sorted set corresponding to the specified iterable
* and comparator.
* <p>
* <code>TreeSet(Iterable iterable, Comparator c)</code>
*/
public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator) {
return sortedSet(iterable.iterator(), comparator);
}
/**
* Return a sorted set corresponding to the specified iterable
* and comparator.
* The specified iterable size is a performance hint.
* <p>
* <code>TreeSet(Iterable iterable, Comparator c)</code>
*/
public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator, int iterableSize) {
return sortedSet(iterable.iterator(), comparator, iterableSize);
}
/**
* Return a sorted set corresponding to the specified iterator.
* <p>
* <code>TreeSet(Iterator iterator)</code>
*/
public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator) {
return sortedSet(iterator, null);
}
/**
* Return a sorted set corresponding to the specified iterator.
* The specified iterator size is a performance hint.
* <p>
* <code>TreeSet(Iterator iterator)</code>
*/
public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator, int iteratorSize) {
return sortedSet(iterator, null, iteratorSize);
}
/**
* Return a sorted set corresponding to the specified iterator
* and comparator.
* <p>
* <code>TreeSet(Iterator iterator, Comparator c)</code>
*/
public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator) {
return sortedSet(list(iterator), comparator);
}
/**
* Return a sorted set corresponding to the specified iterator
* and comparator.
* The specified iterator size is a performance hint.
* <p>
* <code>TreeSet(Iterator iterator, Comparator c)</code>
*/
public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator, int iteratorSize) {
return sortedSet(list(iterator, iteratorSize), comparator);
}
private static <E> TreeSet<E> sortedSet(List<E> list, Comparator<? super E> comparator) {
TreeSet<E> sortedSet = new TreeSet<E>(comparator);
sortedSet.addAll(list);
return sortedSet;
}
/**
* Return a sorted set corresponding to the specified array.
* <p>
* <code>TreeSet(Object[] array)</code>
*/
public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(E... array) {
return sortedSet(array, null);
}
/**
* Return a sorted set corresponding to the specified array
* and comparator.
* <p>
* <code>TreeSet(Object[] array, Comparator c)</code>
*/
public static <E> TreeSet<E> sortedSet(E[] array, Comparator<? super E> comparator) {
TreeSet<E> sortedSet = new TreeSet<E>(comparator);
sortedSet.addAll(Arrays.asList(array));
return sortedSet;
}
// ********** Old School Vector **********
/**
* Return a vector corresponding to the specified iterable.
* This is useful for legacy code that requires a {@link Vector}.
* <p>
* <code>Vector(Iterable iterable)</code>
*/
public static <E> Vector<E> vector(Iterable<? extends E> iterable) {
return vector(iterable.iterator());
}
/**
* Return a vector corresponding to the specified iterable.
* This is useful for legacy code that requires a {@link Vector}.
* <p>
* <code>Vector(Iterable iterable, int size)</code>
*/
public static <E> Vector<E> vector(Iterable<? extends E> iterable, int size) {
return vector(iterable.iterator(), size);
}
/**
* Return a vector corresponding to the specified iterator.
* This is useful for legacy code that requires a {@link Vector}.
* <p>
* <code>Vector(Iterator iterator)</code>
*/
public static <E> Vector<E> vector(Iterator<? extends E> iterator) {
return vector(iterator, new Vector<E>());
}
/**
* Return a vector corresponding to the specified iterator.
* This is useful for legacy code that requires a {@link Vector}.
* <p>
* <code>Vector(Iterator iterator, int size)</code>
*/
public static <E> Vector<E> vector(Iterator<? extends E> iterator, int size) {
return vector(iterator, new Vector<E>(size));
}
private static <E> Vector<E> vector(Iterator<? extends E> iterator, Vector<E> v) {
while (iterator.hasNext()) {
v.addElement(iterator.next());
}
return v;
}
/**
* Return a vector corresponding to the specified array.
* This is useful for legacy code that requires a {@link Vector}.
* <p>
* <code>Vector(Object... array)</code>
*/
public static <E> Vector<E> vector(E... array) {
Vector<E> v = new Vector<E>(array.length);
for (E item : array) {
v.addElement(item);
}
return v;
}
// ********** single-use Iterable **********
/**
* Return a one-use {@link Iterable} for the specified {@link Iterator}.
* Throw an {@link IllegalStateException} if {@link Iterable#iterator()}
* is called more than once.
* As such, this utility should only be used in one-use situations, such as
* a foreach loop.
*/
public static <E> Iterable<E> iterable(Iterator<? extends E> iterator) {
return new SingleUseIterable<E>(iterator);
}
/**
* This is a one-time use iterable that can return a single iterator.
* Once the iterator is returned the iterable is no longer valid.
* As such, this utility should only be used in one-time use situations,
* such as a 'for-each' loop.
*/
public static class SingleUseIterable<E> implements Iterable<E> {
private Iterator<E> iterator;
public SingleUseIterable(Iterator<? extends E> iterator) {
super();
if (iterator == null) {
throw new NullPointerException();
}
this.iterator = new SuperIteratorWrapper<E>(iterator);
}
public Iterator<E> iterator() {
if (this.iterator == null) {
throw new IllegalStateException("This method has already been called."); //$NON-NLS-1$
}
Iterator<E> result = this.iterator;
this.iterator = null;
return result;
}
@Override
public String toString() {
return StringTools.buildToStringFor(this, this.iterator);
}
}
// ********** java.util.Collections enhancements **********
/**
* Return the destination list after the source list has been copied into it.
* @see Collections#copy(List, List)
*/
public static <E> List<E> copy(List<E> dest, List<? extends E> src) {
Collections.copy(dest, src);
return dest;
}
/**
* Return the list after it has been "filled".
* @see Collections#fill(List, Object)
*/
public static <E> List<E> fill(List<E> list, E value) {
Collections.fill(list, value);
return list;
}
/**
* Return the list after it has been "reversed".
* @see Collections#reverse(List)
*/
public static <E> List<E> reverse(List<E> list) {
Collections.reverse(list);
return list;
}
/**
* Return the list after it has been "rotated".
* @see Collections#rotate(List, int)
*/
public static <E> List<E> rotate(List<E> list, int distance) {
Collections.rotate(list, distance);
return list;
}
/**
* Return the list after it has been "shuffled".
* @see Collections#shuffle(List)
*/
public static <E> List<E> shuffle(List<E> list) {
Collections.shuffle(list);
return list;
}
/**
* Return the list after it has been "shuffled".
* @see Collections#shuffle(List, Random)
*/
public static <E> List<E> shuffle(List<E> list, Random random) {
Collections.shuffle(list, random);
return list;
}
/**
* Return the list after it has been "sorted".
* NB: The list is sorted in place as a side-effect.
* @see Collections#sort(List)
*/
public static <E extends Comparable<? super E>> List<E> sort(List<E> list) {
Collections.sort(list);
return list;
}
/**
* Return the list after it has been "sorted".
* NB: The list is sorted in place as a side-effect.
* @see Collections#sort(List, Comparator)
*/
public static <E> List<E> sort(List<E> list, Comparator<? super E> comparator) {
Collections.sort(list, comparator);
return list;
}
/**
* Return the list after the specified elements have been "swapped".
* @see Collections#swap(List, int, int)
*/
public static <E> List<E> swap(List<E> list, int i, int j) {
Collections.swap(list, i, j);
return list;
}
// ********** constructor **********
/**
* Suppress default constructor, ensuring non-instantiability.
*/
private CollectionTools() {
super();
throw new UnsupportedOperationException();
}
}