
com.signalfx.shaded.google.common.collect.Sets Maven / Gradle / Ivy
Show all versions of signalfx-java Show documentation
/*
* Copyright (C) 2007 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.signalfx.shaded.google.common.collect;
import static com.signalfx.shaded.google.common.base.Preconditions.checkArgument;
import static com.signalfx.shaded.google.common.base.Preconditions.checkNotNull;
import static com.signalfx.shaded.google.common.collect.CollectPreconditions.checkNonnegative;
import static java.lang.Math.min;
import static java.util.Arrays.asList;
import com.signalfx.shaded.google.common.annotations.GwtCompatible;
import com.signalfx.shaded.google.common.annotations.GwtIncompatible;
import com.signalfx.shaded.google.common.annotations.J2ktIncompatible;
import com.signalfx.shaded.google.common.base.Predicate;
import com.signalfx.shaded.google.common.base.Predicates;
import com.signalfx.shaded.google.common.collect.Collections2.FilteredCollection;
import com.signalfx.shaded.google.common.math.IntMath;
import com.signalfx.shaded.google.errorprone.annotations.CanIgnoreReturnValue;
import com.signalfx.shaded.google.errorprone.annotations.DoNotCall;
import com.signalfx.shaded.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
import java.util.stream.Collector;
import java.util.stream.Stream;
import com.signalfx.shaded.javax.annotation.CheckForNull;
import com.signalfx.shaded.checkerframework.checker.nullness.qual.NonNull;
import com.signalfx.shaded.checkerframework.checker.nullness.qual.Nullable;
/**
* Static utility methods pertaining to {@link Set} instances. Also see this class's counterparts
* {@link Lists}, {@link Maps} and {@link Queues}.
*
* See the Guava User Guide article on {@code Sets}.
*
* @author Kevin Bourrillion
* @author Jared Levy
* @author Chris Povirk
* @since 2.0
*/
@GwtCompatible(emulated = true)
@ElementTypesAreNonnullByDefault
public final class Sets {
private Sets() {}
/**
* {@link AbstractSet} substitute without the potentially-quadratic {@code removeAll}
* implementation.
*/
abstract static class ImprovedAbstractSet extends AbstractSet {
@Override
public boolean removeAll(Collection c) {
return removeAllImpl(this, c);
}
@Override
public boolean retainAll(Collection c) {
return super.retainAll(checkNotNull(c)); // GWT compatibility
}
}
/**
* Returns an immutable set instance containing the given enum elements. Internally, the returned
* set will be backed by an {@link EnumSet}.
*
*
The iteration order of the returned set follows the enum's iteration order, not the order in
* which the elements are provided to the method.
*
* @param anElement one of the elements the set should contain
* @param otherElements the rest of the elements the set should contain
* @return an immutable set containing those elements, minus duplicates
*/
@GwtCompatible(serializable = true)
public static > ImmutableSet immutableEnumSet(
E anElement, E... otherElements) {
return ImmutableEnumSet.asImmutable(EnumSet.of(anElement, otherElements));
}
/**
* Returns an immutable set instance containing the given enum elements. Internally, the returned
* set will be backed by an {@link EnumSet}.
*
*
The iteration order of the returned set follows the enum's iteration order, not the order in
* which the elements appear in the given collection.
*
* @param elements the elements, all of the same {@code enum} type, that the set should contain
* @return an immutable set containing those elements, minus duplicates
*/
@GwtCompatible(serializable = true)
public static > ImmutableSet immutableEnumSet(Iterable elements) {
if (elements instanceof ImmutableEnumSet) {
return (ImmutableEnumSet) elements;
} else if (elements instanceof Collection) {
Collection collection = (Collection) elements;
if (collection.isEmpty()) {
return ImmutableSet.of();
} else {
return ImmutableEnumSet.asImmutable(EnumSet.copyOf(collection));
}
} else {
Iterator itr = elements.iterator();
if (itr.hasNext()) {
EnumSet enumSet = EnumSet.of(itr.next());
Iterators.addAll(enumSet, itr);
return ImmutableEnumSet.asImmutable(enumSet);
} else {
return ImmutableSet.of();
}
}
}
/**
* Returns a {@code Collector} that accumulates the input elements into a new {@code ImmutableSet}
* with an implementation specialized for enums. Unlike {@link ImmutableSet#toImmutableSet}, the
* resulting set will iterate over elements in their enum definition order, not encounter order.
*
* @since 21.0
*/
public static > Collector> toImmutableEnumSet() {
return CollectCollectors.toImmutableEnumSet();
}
/**
* Returns a new, mutable {@code EnumSet} instance containing the given elements in their
* natural order. This method behaves identically to {@link EnumSet#copyOf(Collection)}, but also
* accepts non-{@code Collection} iterables and empty iterables.
*/
public static > EnumSet newEnumSet(
Iterable iterable, Class elementType) {
EnumSet set = EnumSet.noneOf(elementType);
Iterables.addAll(set, iterable);
return set;
}
// HashSet
/**
* Creates a mutable, initially empty {@code HashSet} instance.
*
*
Note: if mutability is not required, use {@link ImmutableSet#of()} instead. If {@code
* E} is an {@link Enum} type, use {@link EnumSet#noneOf} instead. Otherwise, strongly consider
* using a {@code LinkedHashSet} instead, at the cost of increased memory footprint, to get
* deterministic iteration behavior.
*
*
Note: this method is now unnecessary and should be treated as deprecated. Instead,
* use the {@code HashSet} constructor directly, taking advantage of "diamond"
* syntax.
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static HashSet newHashSet() {
return new HashSet<>();
}
/**
* Creates a mutable {@code HashSet} instance initially containing the given elements.
*
*
Note: if elements are non-null and won't be added or removed after this point, use
* {@link ImmutableSet#of()} or {@link ImmutableSet#copyOf(Object[])} instead. If {@code E} is an
* {@link Enum} type, use {@link EnumSet#of(Enum, Enum[])} instead. Otherwise, strongly consider
* using a {@code LinkedHashSet} instead, at the cost of increased memory footprint, to get
* deterministic iteration behavior.
*
*
This method is just a small convenience, either for {@code newHashSet(}{@link Arrays#asList
* asList}{@code (...))}, or for creating an empty set then calling {@link Collections#addAll}.
* This method is not actually very useful and will likely be deprecated in the future.
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static HashSet newHashSet(E... elements) {
HashSet set = newHashSetWithExpectedSize(elements.length);
Collections.addAll(set, elements);
return set;
}
/**
* Creates a mutable {@code HashSet} instance containing the given elements. A very thin
* convenience for creating an empty set then calling {@link Collection#addAll} or {@link
* Iterables#addAll}.
*
*
Note: if mutability is not required and the elements are non-null, use {@link
* ImmutableSet#copyOf(Iterable)} instead. (Or, change {@code elements} to be a {@link
* FluentIterable} and call {@code elements.toSet()}.)
*
*
Note: if {@code E} is an {@link Enum} type, use {@link #newEnumSet(Iterable, Class)}
* instead.
*
*
Note: if {@code elements} is a {@link Collection}, you don't need this method.
* Instead, use the {@code HashSet} constructor directly, taking advantage of "diamond"
* syntax.
*
*
Overall, this method is not very useful and will likely be deprecated in the future.
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static HashSet newHashSet(Iterable elements) {
return (elements instanceof Collection)
? new HashSet((Collection) elements)
: newHashSet(elements.iterator());
}
/**
* Creates a mutable {@code HashSet} instance containing the given elements. A very thin
* convenience for creating an empty set and then calling {@link Iterators#addAll}.
*
*
Note: if mutability is not required and the elements are non-null, use {@link
* ImmutableSet#copyOf(Iterator)} instead.
*
*
Note: if {@code E} is an {@link Enum} type, you should create an {@link EnumSet}
* instead.
*
*
Overall, this method is not very useful and will likely be deprecated in the future.
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static HashSet newHashSet(Iterator elements) {
HashSet set = newHashSet();
Iterators.addAll(set, elements);
return set;
}
/**
* Returns a new hash set using the smallest initial table size that can hold {@code expectedSize}
* elements without resizing. Note that this is not what {@link HashSet#HashSet(int)} does, but it
* is what most users want and expect it to do.
*
*
This behavior can't be broadly guaranteed, but has been tested with OpenJDK 1.7 and 1.8.
*
* @param expectedSize the number of elements you expect to add to the returned set
* @return a new, empty hash set with enough capacity to hold {@code expectedSize} elements
* without resizing
* @throws IllegalArgumentException if {@code expectedSize} is negative
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static HashSet newHashSetWithExpectedSize(
int expectedSize) {
return new HashSet<>(Maps.capacity(expectedSize));
}
/**
* Creates a thread-safe set backed by a hash map. The set is backed by a {@link
* ConcurrentHashMap} instance, and thus carries the same concurrency guarantees.
*
*
Unlike {@code HashSet}, this class does NOT allow {@code null} to be used as an element. The
* set is serializable.
*
* @return a new, empty thread-safe {@code Set}
* @since 15.0
*/
public static Set newConcurrentHashSet() {
return Platform.newConcurrentHashSet();
}
/**
* Creates a thread-safe set backed by a hash map and containing the given elements. The set is
* backed by a {@link ConcurrentHashMap} instance, and thus carries the same concurrency
* guarantees.
*
*
Unlike {@code HashSet}, this class does NOT allow {@code null} to be used as an element. The
* set is serializable.
*
* @param elements the elements that the set should contain
* @return a new thread-safe set containing those elements (minus duplicates)
* @throws NullPointerException if {@code elements} or any of its contents is null
* @since 15.0
*/
public static Set newConcurrentHashSet(Iterable elements) {
Set set = newConcurrentHashSet();
Iterables.addAll(set, elements);
return set;
}
// LinkedHashSet
/**
* Creates a mutable, empty {@code LinkedHashSet} instance.
*
*
Note: if mutability is not required, use {@link ImmutableSet#of()} instead.
*
*
Note: this method is now unnecessary and should be treated as deprecated. Instead,
* use the {@code LinkedHashSet} constructor directly, taking advantage of "diamond"
* syntax.
*
* @return a new, empty {@code LinkedHashSet}
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static LinkedHashSet newLinkedHashSet() {
return new LinkedHashSet<>();
}
/**
* Creates a mutable {@code LinkedHashSet} instance containing the given elements in order.
*
*
Note: if mutability is not required and the elements are non-null, use {@link
* ImmutableSet#copyOf(Iterable)} instead.
*
*
Note: if {@code elements} is a {@link Collection}, you don't need this method.
* Instead, use the {@code LinkedHashSet} constructor directly, taking advantage of "diamond"
* syntax.
*
*
Overall, this method is not very useful and will likely be deprecated in the future.
*
* @param elements the elements that the set should contain, in order
* @return a new {@code LinkedHashSet} containing those elements (minus duplicates)
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static LinkedHashSet newLinkedHashSet(
Iterable elements) {
if (elements instanceof Collection) {
return new LinkedHashSet<>((Collection) elements);
}
LinkedHashSet set = newLinkedHashSet();
Iterables.addAll(set, elements);
return set;
}
/**
* Creates a {@code LinkedHashSet} instance, with a high enough "initial capacity" that it
* should hold {@code expectedSize} elements without growth. This behavior cannot be
* broadly guaranteed, but it is observed to be true for OpenJDK 1.7. It also can't be guaranteed
* that the method isn't inadvertently oversizing the returned set.
*
* @param expectedSize the number of elements you expect to add to the returned set
* @return a new, empty {@code LinkedHashSet} with enough capacity to hold {@code expectedSize}
* elements without resizing
* @throws IllegalArgumentException if {@code expectedSize} is negative
* @since 11.0
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static LinkedHashSet newLinkedHashSetWithExpectedSize(
int expectedSize) {
return new LinkedHashSet<>(Maps.capacity(expectedSize));
}
// TreeSet
/**
* Creates a mutable, empty {@code TreeSet} instance sorted by the natural sort ordering of
* its elements.
*
*
Note: if mutability is not required, use {@link ImmutableSortedSet#of()} instead.
*
*
Note: this method is now unnecessary and should be treated as deprecated. Instead,
* use the {@code TreeSet} constructor directly, taking advantage of "diamond"
* syntax.
*
* @return a new, empty {@code TreeSet}
*/
@SuppressWarnings({
"rawtypes", // https://github.com/google/guava/issues/989
"NonApiType", // acts as a direct substitute for a constructor call
})
public static TreeSet newTreeSet() {
return new TreeSet<>();
}
/**
* Creates a mutable {@code TreeSet} instance containing the given elements sorted by their
* natural ordering.
*
*
Note: if mutability is not required, use {@link ImmutableSortedSet#copyOf(Iterable)}
* instead.
*
*
Note: If {@code elements} is a {@code SortedSet} with an explicit comparator, this
* method has different behavior than {@link TreeSet#TreeSet(SortedSet)}, which returns a {@code
* TreeSet} with that comparator.
*
*
Note: this method is now unnecessary and should be treated as deprecated. Instead,
* use the {@code TreeSet} constructor directly, taking advantage of "diamond"
* syntax.
*
*
This method is just a small convenience for creating an empty set and then calling {@link
* Iterables#addAll}. This method is not very useful and will likely be deprecated in the future.
*
* @param elements the elements that the set should contain
* @return a new {@code TreeSet} containing those elements (minus duplicates)
*/
@SuppressWarnings({
"rawtypes", // https://github.com/google/guava/issues/989
"NonApiType", // acts as a direct substitute for a constructor call
})
public static TreeSet newTreeSet(Iterable elements) {
TreeSet set = newTreeSet();
Iterables.addAll(set, elements);
return set;
}
/**
* Creates a mutable, empty {@code TreeSet} instance with the given comparator.
*
*
Note: if mutability is not required, use {@code
* ImmutableSortedSet.orderedBy(comparator).build()} instead.
*
*
Note: this method is now unnecessary and should be treated as deprecated. Instead,
* use the {@code TreeSet} constructor directly, taking advantage of "diamond"
* syntax. One caveat to this is that the {@code TreeSet} constructor uses a null {@code
* Comparator} to mean "natural ordering," whereas this factory rejects null. Clean your code
* accordingly.
*
* @param comparator the comparator to use to sort the set
* @return a new, empty {@code TreeSet}
* @throws NullPointerException if {@code comparator} is null
*/
@SuppressWarnings("NonApiType") // acts as a direct substitute for a constructor call
public static TreeSet newTreeSet(
Comparator comparator) {
return new TreeSet<>(checkNotNull(comparator));
}
/**
* Creates an empty {@code Set} that uses identity to determine equality. It compares object
* references, instead of calling {@code equals}, to determine whether a provided object matches
* an element in the set. For example, {@code contains} returns {@code false} when passed an
* object that equals a set member, but isn't the same instance. This behavior is similar to the
* way {@code IdentityHashMap} handles key lookups.
*
* @since 8.0
*/
public static Set newIdentityHashSet() {
return Collections.newSetFromMap(Maps.newIdentityHashMap());
}
/**
* Creates an empty {@code CopyOnWriteArraySet} instance.
*
*
Note: if you need an immutable empty {@link Set}, use {@link Collections#emptySet}
* instead.
*
* @return a new, empty {@code CopyOnWriteArraySet}
* @since 12.0
*/
@J2ktIncompatible
@GwtIncompatible // CopyOnWriteArraySet
public static CopyOnWriteArraySet newCopyOnWriteArraySet() {
return new CopyOnWriteArraySet<>();
}
/**
* Creates a {@code CopyOnWriteArraySet} instance containing the given elements.
*
* @param elements the elements that the set should contain, in order
* @return a new {@code CopyOnWriteArraySet} containing those elements
* @since 12.0
*/
@J2ktIncompatible
@GwtIncompatible // CopyOnWriteArraySet
public static CopyOnWriteArraySet newCopyOnWriteArraySet(
Iterable elements) {
// We copy elements to an ArrayList first, rather than incurring the
// quadratic cost of adding them to the COWAS directly.
Collection elementsCollection =
(elements instanceof Collection)
? (Collection) elements
: Lists.newArrayList(elements);
return new CopyOnWriteArraySet<>(elementsCollection);
}
/**
* Creates an {@code EnumSet} consisting of all enum values that are not in the specified
* collection. If the collection is an {@link EnumSet}, this method has the same behavior as
* {@link EnumSet#complementOf}. Otherwise, the specified collection must contain at least one
* element, in order to determine the element type. If the collection could be empty, use {@link
* #complementOf(Collection, Class)} instead of this method.
*
* @param collection the collection whose complement should be stored in the enum set
* @return a new, modifiable {@code EnumSet} containing all values of the enum that aren't present
* in the given collection
* @throws IllegalArgumentException if {@code collection} is not an {@code EnumSet} instance and
* contains no elements
*/
@J2ktIncompatible
@GwtIncompatible // EnumSet.complementOf
public static > EnumSet complementOf(Collection collection) {
if (collection instanceof EnumSet) {
return EnumSet.complementOf((EnumSet) collection);
}
checkArgument(
!collection.isEmpty(), "collection is empty; use the other version of this method");
Class type = collection.iterator().next().getDeclaringClass();
return makeComplementByHand(collection, type);
}
/**
* Creates an {@code EnumSet} consisting of all enum values that are not in the specified
* collection. This is equivalent to {@link EnumSet#complementOf}, but can act on any input
* collection, as long as the elements are of enum type.
*
* @param collection the collection whose complement should be stored in the {@code EnumSet}
* @param type the type of the elements in the set
* @return a new, modifiable {@code EnumSet} initially containing all the values of the enum not
* present in the given collection
*/
@J2ktIncompatible
@GwtIncompatible // EnumSet.complementOf
public static > EnumSet complementOf(
Collection collection, Class type) {
checkNotNull(collection);
return (collection instanceof EnumSet)
? EnumSet.complementOf((EnumSet) collection)
: makeComplementByHand(collection, type);
}
@J2ktIncompatible
@GwtIncompatible
private static > EnumSet makeComplementByHand(
Collection collection, Class type) {
EnumSet result = EnumSet.allOf(type);
result.removeAll(collection);
return result;
}
/**
* Returns a set backed by the specified map. The resulting set displays the same ordering,
* concurrency, and performance characteristics as the backing map. In essence, this factory
* method provides a {@link Set} implementation corresponding to any {@link Map} implementation.
* There is no need to use this method on a {@link Map} implementation that already has a
* corresponding {@link Set} implementation (such as {@link java.util.HashMap} or {@link
* java.util.TreeMap}).
*
*
Each method invocation on the set returned by this method results in exactly one method
* invocation on the backing map or its {@code keySet} view, with one exception. The {@code
* addAll} method is implemented as a sequence of {@code put} invocations on the backing map.
*
*
The specified map must be empty at the time this method is invoked, and should not be
* accessed directly after this method returns. These conditions are ensured if the map is created
* empty, passed directly to this method, and no reference to the map is retained, as illustrated
* in the following code fragment:
*
*
{@code
* Set