ptolemaeus.commons.collections.SetUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of commons Show documentation
Show all versions of commons Show documentation
a collection of utilities written in the pursuit of other objectives when an existing solution doesn't exist. Many are collection-driven, such as MultiIndexMap, StreamUtils, MapUtils, SetUtils, etc.
The newest version!
/**
* MIT License
*
* Copyright (c) 2023 Lockheed Martin Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package ptolemaeus.commons.collections;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.NavigableSet;
import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.collections4.set.UnmodifiableNavigableSet;
/**
* A collection of {@code static} utility/convenience methods for getting unmodifiable and insertion order
* preserving {@link Set}s and unmodifiable {@link NavigableSet}s. This can function as a drop-in replacement for
* the static {@link Set} methods.
*
*
* - {@link Set#copyOf(java.util.Collection)}
* - the {@link Set#of()} series
*
*
*
* and also provides
*
*
*
* - {@link SetUtils#empty()}
* - {@link SetUtils#emptyNavigable()}
* - {@link SetUtils#navigableSetOf(Comparable...)}
* - {@link SetUtils#navigableSetOf(Comparator, Object...)}
*
*
* @author Ryan Moser, [email protected]
*/
public final class SetUtils {
/**
* Do nothing constructor
*/
private SetUtils() {
// do nothing
}
/**
* Perform and return the union of the two provided {@link Collection}s
*
* @param the element type of the resulting {@link Set}
* @param c1 the first {@link Collection}
* @param c2 the second {@link Collection}
* @return the union of {@code c1} and {@code c2}
* @implNote per the definition of {@link Set}, if there exists elements in {@code c2} such that {@code c1.contains}
* will return {@code true}, only those which are found in {@code c1} will be in the answer. Naturally,
* any duplicates in either set will also not appear in the result.
*/
public static Set union(final Collection extends E> c1, final Collection extends E> c2) {
final Set answer = new LinkedHashSet<>();
answer.addAll(c1);
answer.addAll(c2);
return answer;
}
/**
* Get a new, empty, and modifiable insertion order preserving {@link Set}
*
* @param the element type
* @return the new {@link Set}
*/
public static Set empty() {
return new LinkedHashSet<>();
}
/**
* Get a new, empty, and modifiable {@link NavigableSet}
*
* @param the element type
* @return the new {@link NavigableSet}
*/
public static > NavigableSet emptyNavigable() {
return new TreeSet<>();
}
/**
* Returns an unmodifiable set containing an arbitrary number of elements.
* See Unmodifiable Sets for details.
*
* @apiNote This method also accepts a single array as an argument. The element type of the resulting set will be
* the component type of the array, and the size of the set will be equal to the length of the array. To
* create a set with a single element that is an array, do the following:
*
*
* {@code
* String[] array = ... ;
* Set list = Set.of(array);
* }
*
*
* @param the {@code Set}'s element type
* @param elements the elements to be contained in the set
* @return a {@code Set} containing the specified elements
* @throws IllegalArgumentException if there are any duplicate elements
* @throws NullPointerException if an element is {@code null} or if the array is {@code null}
*/
@SafeVarargs
public static Set of(final E... elements) {
return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(elements)));
}
/**
* Returns an unmodifiable {@link NavigableSet} containing an arbitrary number of elements.
* See Unmodifiable Sets for details.
*
* @apiNote This method also accepts a single array as an argument. The element type of the resulting set will be
* the component type of the array, and the size of the set will be equal to the length of the array. To
* create a set with a single element that is an array, do the following:
*
*
* {@code
* String[] array = ... ;
* Set list = SetUtils.of(array);
* }
*
*
* @param the {@code Set}'s element type
* @param elements the elements to be contained in the set
* @return a {@code Set} containing the specified elements
*/
@SafeVarargs
public static > NavigableSet navigableSetOf(final E... elements) {
return UnmodifiableNavigableSet.unmodifiableNavigableSet(new TreeSet<>(Arrays.asList(elements)));
}
/**
* Returns an unmodifiable {@link NavigableSet} containing an arbitrary number of elements.
* See Unmodifiable Sets for details.
*
* @apiNote This method also accepts a single array as an argument. The element type of the resulting set will be
* the component type of the array, and the size of the set will be equal to the length of the array. To
* create a set with a single element that is an array, do the following:
*
*
* {@code
* String[] array = ... ;
* Set list = SetUtils.of(array);
* }
*
*
* @param the {@code Set}'s element type
* @param comparator the {@link Comparator} to use in the {@link NavigableSet}
* @param elements the elements to be contained in the set
* @return a {@code Set} containing the specified elements
*/
@SafeVarargs
public static NavigableSet navigableSetOf(final Comparator comparator, final E... elements) {
NavigableSet temp = new TreeSet<>(comparator);
temp.addAll(Arrays.asList(elements));
return UnmodifiableNavigableSet.unmodifiableNavigableSet(temp);
}
/**
* Returns an unmodifiable Set containing the elements of the given Collection. The
* given Collection must not be null. If the given Collection contains duplicate elements, an arbitrary element of
* the duplicates is preserved. If the given Collection is subsequently modified, the returned Set will not reflect
* such modifications.
*
* @param the {@link Set}'s element type
* @param coll a {@link Collection} from which elements are drawn, must be non-null
* @return a {@link Set} containing the elements of the given {@link Collection}
*/
public static Set copyOf(final Collection extends E> coll) {
return Collections.unmodifiableSet(new LinkedHashSet<>(coll));
}
/**
* Returns an unmodifiable Set containing the elements of the given Collection. The
* given Collection must not be null. If the given Collection contains duplicate elements, an arbitrary element of
* the duplicates is preserved. If the given Collection is subsequently modified, the returned Set will not reflect
* such modifications.
*
* @param the {@link SortedSet}'s element type
* @param coll a {@link SortedSet} from which elements are drawn, must be non-null
* @return a {@link SortedSet} containing the elements of the given {@link Collection}
*/
public static > NavigableSet copyOf(final NavigableSet coll) {
return UnmodifiableNavigableSet.unmodifiableNavigableSet(coll); // Apache
}
/**
* Return a new set equal to 'original' but without 'excludeMe'
* @param the class of items in the set
* @param original the original set
* @param excludeMe the item to be excluded
* @return the new set
*/
public static Set subtract(final Set original, final E excludeMe) {
Set answer = new LinkedHashSet<>(original);
if (!answer.remove(excludeMe)) {
throw new IllegalArgumentException("Item was not in the set");
}
return answer;
}
/**
* Return the set difference, i.e., the set of elements that are in 'primary' but not in 'excluded'
* @param the class of objects in the collections
* @param primary the larger collection
* @param excluded the items to be excluded
* @return the set of elements that are in 'primary' but not in 'excludeMe'
*/
public static Set setDiff(final Collection primary, final Collection excluded) {
Set answer = new LinkedHashSet<>(primary);
answer.removeAll(excluded);
return answer;
}
/**
* Find the intersection of two sets, without modifying either of them
* @param firstSet the first set or collection
* @param secondSet the second set
* @param the class of items in the set
* @return the set of items that are present in both inputs
*/
public static Set getIntersection(final Collection extends E> firstSet,
final Set extends E> secondSet) {
Objects.requireNonNull(firstSet, "First set may not be null");
Objects.requireNonNull(secondSet, "Second set may not be null");
if (firstSet.isEmpty() || secondSet.isEmpty()) {
return SetUtils.of(); // return fast
}
Set answer = new LinkedHashSet<>(firstSet);
answer.retainAll(secondSet);
return answer;
}
}