All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.common.collect.Collections2 Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2008 The Guava Authors
 *
 * Licensed 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 com.google.common.collect;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.primitives.Ints;

import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * Provides static methods for working with {@code Collection} instances.
 *
 * @author Chris Povirk
 * @author Mike Bostock
 * @author Jared Levy
 * @since 2.0 (imported from Google Collections Library)
 */
@GwtCompatible
public final class Collections2 {
  private Collections2() {}

  /**
   * Returns the elements of {@code unfiltered} that satisfy a predicate. The
   * returned collection is a live view of {@code unfiltered}; changes to one
   * affect the other.
   *
   * 

The resulting collection's iterator does not support {@code remove()}, * but all other collection methods are supported. When given an element that * doesn't satisfy the predicate, the collection's {@code add()} and {@code * addAll()} methods throw an {@link IllegalArgumentException}. When methods * such as {@code removeAll()} and {@code clear()} are called on the filtered * collection, only elements that satisfy the filter will be removed from the * underlying collection. * *

The returned collection isn't threadsafe or serializable, even if * {@code unfiltered} is. * *

Many of the filtered collection's methods, such as {@code size()}, * iterate across every element in the underlying collection and determine * which elements satisfy the filter. When a live view is not needed, * it may be faster to copy {@code Iterables.filter(unfiltered, predicate)} * and use the copy. * *

Warning: {@code predicate} must be consistent with equals, * as documented at {@link Predicate#apply}. Do not provide a predicate such * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent * with equals. (See {@link Iterables#filter(Iterable, Class)} for related * functionality.) */ // TODO(kevinb): how can we omit that Iterables link when building gwt // javadoc? public static Collection filter( Collection unfiltered, Predicate predicate) { if (unfiltered instanceof FilteredCollection) { // Support clear(), removeAll(), and retainAll() when filtering a filtered // collection. return ((FilteredCollection) unfiltered).createCombined(predicate); } return new FilteredCollection( checkNotNull(unfiltered), checkNotNull(predicate)); } /** * Delegates to {@link Collection#contains}. Returns {@code false} if the * {@code contains} method throws a {@code ClassCastException}. */ static boolean safeContains(Collection collection, Object object) { try { return collection.contains(object); } catch (ClassCastException e) { return false; } } static class FilteredCollection implements Collection { final Collection unfiltered; final Predicate predicate; FilteredCollection(Collection unfiltered, Predicate predicate) { this.unfiltered = unfiltered; this.predicate = predicate; } FilteredCollection createCombined(Predicate newPredicate) { return new FilteredCollection(unfiltered, Predicates.and(predicate, newPredicate)); // . above needed to compile in JDK 5 } @Override public boolean add(E element) { checkArgument(predicate.apply(element)); return unfiltered.add(element); } @Override public boolean addAll(Collection collection) { for (E element : collection) { checkArgument(predicate.apply(element)); } return unfiltered.addAll(collection); } @Override public void clear() { Iterables.removeIf(unfiltered, predicate); } @Override public boolean contains(Object element) { try { // unsafe cast can result in a CCE from predicate.apply(), which we // will catch @SuppressWarnings("unchecked") E e = (E) element; /* * We check whether e satisfies the predicate, when we really mean to * check whether the element contained in the set does. This is ok as * long as the predicate is consistent with equals, as required. */ return predicate.apply(e) && unfiltered.contains(element); } catch (NullPointerException e) { return false; } catch (ClassCastException e) { return false; } } @Override public boolean containsAll(Collection collection) { for (Object element : collection) { if (!contains(element)) { return false; } } return true; } @Override public boolean isEmpty() { return !Iterators.any(unfiltered.iterator(), predicate); } @Override public Iterator iterator() { return Iterators.filter(unfiltered.iterator(), predicate); } @Override public boolean remove(Object element) { try { // unsafe cast can result in a CCE from predicate.apply(), which we // will catch @SuppressWarnings("unchecked") E e = (E) element; // See comment in contains() concerning predicate.apply(e) return predicate.apply(e) && unfiltered.remove(element); } catch (NullPointerException e) { return false; } catch (ClassCastException e) { return false; } } @Override public boolean removeAll(final Collection collection) { checkNotNull(collection); Predicate combinedPredicate = new Predicate() { @Override public boolean apply(E input) { return predicate.apply(input) && collection.contains(input); } }; return Iterables.removeIf(unfiltered, combinedPredicate); } @Override public boolean retainAll(final Collection collection) { checkNotNull(collection); Predicate combinedPredicate = new Predicate() { @Override public boolean apply(E input) { // See comment in contains() concerning predicate.apply(e) return predicate.apply(input) && !collection.contains(input); } }; return Iterables.removeIf(unfiltered, combinedPredicate); } @Override public int size() { return Iterators.size(iterator()); } @Override public Object[] toArray() { // creating an ArrayList so filtering happens once return Lists.newArrayList(iterator()).toArray(); } @Override public T[] toArray(T[] array) { return Lists.newArrayList(iterator()).toArray(array); } @Override public String toString() { return Iterators.toString(iterator()); } } /** * Returns a collection that applies {@code function} to each element of * {@code fromCollection}. The returned collection is a live view of {@code * fromCollection}; changes to one affect the other. * *

The returned collection's {@code add()} and {@code addAll()} methods * throw an {@link UnsupportedOperationException}. All other collection * methods are supported, as long as {@code fromCollection} supports them. * *

The returned collection isn't threadsafe or serializable, even if * {@code fromCollection} is. * *

When a live view is not needed, it may be faster to copy the * transformed collection and use the copy. * *

If the input {@code Collection} is known to be a {@code List}, consider * {@link Lists#transform}. If only an {@code Iterable} is available, use * {@link Iterables#transform}. */ public static Collection transform(Collection fromCollection, Function function) { return new TransformedCollection(fromCollection, function); } static class TransformedCollection extends AbstractCollection { final Collection fromCollection; final Function function; TransformedCollection(Collection fromCollection, Function function) { this.fromCollection = checkNotNull(fromCollection); this.function = checkNotNull(function); } @Override public void clear() { fromCollection.clear(); } @Override public boolean isEmpty() { return fromCollection.isEmpty(); } @Override public Iterator iterator() { return Iterators.transform(fromCollection.iterator(), function); } @Override public int size() { return fromCollection.size(); } } /** * Returns {@code true} if the collection {@code self} contains all of the * elements in the collection {@code c}. * *

This method iterates over the specified collection {@code c}, checking * each element returned by the iterator in turn to see if it is contained in * the specified collection {@code self}. If all elements are so contained, * {@code true} is returned, otherwise {@code false}. * * @param self a collection which might contain all elements in {@code c} * @param c a collection whose elements might be contained by {@code self} */ static boolean containsAllImpl(Collection self, Collection c) { checkNotNull(self); for (Object o : c) { if (!self.contains(o)) { return false; } } return true; } /** * An implementation of {@link Collection#toString()}. */ static String toStringImpl(final Collection collection) { StringBuilder sb = newStringBuilderForCollection(collection.size()).append('['); STANDARD_JOINER.appendTo( sb, Iterables.transform(collection, new Function() { @Override public Object apply(Object input) { return input == collection ? "(this Collection)" : input; } })); return sb.append(']').toString(); } /** * Returns best-effort-sized StringBuilder based on the given collection size. */ static StringBuilder newStringBuilderForCollection(int size) { checkArgument(size >= 0, "size must be non-negative"); return new StringBuilder((int) Math.min(size * 8L, Ints.MAX_POWER_OF_TWO)); } /** * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 */ static Collection cast(Iterable iterable) { return (Collection) iterable; } static final Joiner STANDARD_JOINER = Joiner.on(", "); // TODO(user): Maybe move the mathematical methods to a separate // package-permission class. }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy