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

io.permazen.util.NavigableSets Maven / Gradle / Ivy

The newest version!

/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.util;

import com.google.common.base.Preconditions;

import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.NavigableSet;
import java.util.stream.Collectors;

/**
 * Utility methods relating to {@link NavigableSet}.
 */
public final class NavigableSets {

    private NavigableSets() {
    }

    /**
     * Create a read-only view of the intersection of two or more {@link NavigableSet}s that have a consistent sort order.
     * The {@linkplain NavigableSet#comparator Comparator}s of the sets must all be {@linkplain Comparator#equals equal}
     * (or else all null, for natural ordering).
     *
     * 

* The returned intersection iterates efficiently: a complete iteration requires O(N * M) queries, where * N is the size of the smallest set, and M is the number of sets. * * @param sets the sets to intersect * @param element type * @return the intersection of all {@code sets} * @throws IllegalArgumentException if the {@code sets} do not have equal {@link Comparator}s * @throws IllegalArgumentException if {@code sets}, or any {@link NavigableSet} therein, is null */ public static NavigableSet intersection(Collection> sets) { Preconditions.checkArgument(sets != null, "null sets"); if (sets.stream().anyMatch(EmptyNavigableSet.class::isInstance)) return new EmptyNavigableSet<>(null); return new IntersectionNavigableSet<>(sets); } /** * Create a read-only view of the intersection of two or more {@link NavigableSet}s that have a consistent sort order. * The {@linkplain NavigableSet#comparator Comparator}s of the sets must all be {@linkplain Comparator#equals equal} * (or else all null, for natural ordering). * *

* The returned intersection iterates efficiently: a complete iteration takes time O(N * M) where * N is the size of the smallest set, and M is the number of sets. * * @param sets the sets to intersect * @param element type * @return the intersection of all {@code sets} * @throws IllegalArgumentException if the {@code sets} do not have equal {@link Comparator}s * @throws IllegalArgumentException if {@code sets}, or any {@link NavigableSet} therein, is null */ @SafeVarargs @SuppressWarnings("varargs") public static NavigableSet intersection(NavigableSet... sets) { Preconditions.checkArgument(sets != null, "null sets"); return NavigableSets.intersection(Arrays.asList(sets)); } /** * Create a read-only view of the union of two or more {@link NavigableSet}s that have a consistent sort order. * The {@linkplain NavigableSet#comparator Comparator}s of the sets must all be {@linkplain Comparator#equals equal} * (or else all null, for natural ordering). * * @param sets the sets to union * @param element type * @return the union of all {@code sets} * @throws IllegalArgumentException if the {@code sets} do not have equal {@link Comparator}s * @throws IllegalArgumentException if {@code sets}, or any {@link NavigableSet} therein, is null */ @SafeVarargs @SuppressWarnings("varargs") public static NavigableSet union(NavigableSet... sets) { Preconditions.checkArgument(sets != null, "null sets"); return NavigableSets.union(Arrays.asList(sets)); } /** * Create a read-only view of the union of two or more {@link NavigableSet}s that have a consistent sort order. * The {@linkplain NavigableSet#comparator Comparator}s of the sets must all be {@linkplain Comparator#equals equal} * (or else all null, for natural ordering). * * @param sets the sets to union * @param element type * @return the union of all {@code sets} * @throws IllegalArgumentException if the {@code sets} do not have equal {@link Comparator}s * @throws IllegalArgumentException if {@code sets}, or any {@link NavigableSet} therein, is null */ public static NavigableSet union(Collection> sets) { Preconditions.checkArgument(sets != null, "null sets"); sets = sets.stream() .filter(set -> !(set instanceof EmptyNavigableSet)) .collect(Collectors.toList()); return sets.isEmpty() ? new EmptyNavigableSet<>(null) : new UnionNavigableSet<>(sets); } /** * Create a read-only view of the difference of two {@link NavigableSet}s that have a consistent sort order. * That is, a set containing all elements contained in the first set but not the second. * The {@linkplain NavigableSet#comparator Comparator}s of the sets must all be {@linkplain Comparator#equals equal} * (or else all null, for natural ordering). * * @param set1 original set * @param set2 set of elements to exclude from {@code set1} * @param element type * @return the difference of {@code set1} and {@code set2} * @throws IllegalArgumentException if the {@code set1} and {@code set2} do not have equal {@link Comparator}s * @throws IllegalArgumentException if either parameter is is null */ public static NavigableSet difference(NavigableSet set1, NavigableSet set2) { if (set1 instanceof EmptyNavigableSet || set2 instanceof EmptyNavigableSet) return set1; return new DifferenceNavigableSet<>(set1, set2); } /** * Create a read-only view of the symmetric difference of two {@link NavigableSet}s that have a consistent sort order. * That is, the set containing all elements contained in the first set or the second set, but not in both sets. * The {@linkplain NavigableSet#comparator Comparator}s of the sets must all be {@linkplain Comparator#equals equal} * (or else all null, for natural ordering). * * @param set1 first set * @param set2 second set * @param element type * @return the symmetric difference of {@code set1} and {@code set2} * @throws IllegalArgumentException if the {@code set1} and {@code set2} do not have equal {@link Comparator}s * @throws IllegalArgumentException if either parameter is is null */ public static NavigableSet symmetricDifference(NavigableSet set1, NavigableSet set2) { if (set1 instanceof EmptyNavigableSet) return set2; if (set2 instanceof EmptyNavigableSet) return set1; return NavigableSets.difference(NavigableSets.union(set1, set2), NavigableSets.intersection(set1, set2)); } /** * Create a {@link NavigableSet} containing a single element and natural ordering. * * @param value singleton value * @param element type * @return singleton set * @throws IllegalArgumentException if {@code value} is null or * {@code value}'s class has no natural ordering (i.e., does not implement {@link Comparable}) */ public static NavigableSet singleton(E value) { return NavigableSets.singleton(null, value); } /** * Create a {@link NavigableSet} containing a single element. * * @param comparator comparator, or null for natural ordering * @param value singleton value (possibly null) * @param element type * @return singleton set * @throws IllegalArgumentException if {@code comparator} is null and either {@code value} is null or * {@code value}'s class has no natural ordering (i.e., does not implement {@link Comparable}) */ public static NavigableSet singleton(Comparator comparator, E value) { return new SingletonNavigableSet<>(comparator, value); } /** * Create an empty {@link NavigableSet}. * The returned set's {@link NavigableSet#comparator comparator()} method will return null. * * @param element type * @return empty set */ public static NavigableSet empty() { return NavigableSets.empty(null); } /** * Create an empty {@link NavigableSet} with a specified {@link Comparator}. * * @param comparator comparator, or null for natural ordering * @param element type * @return empty set */ public static NavigableSet empty(Comparator comparator) { return new EmptyNavigableSet<>(comparator); } /** * Return the given {@link Comparator}, or natural order {@link Comparator} if the given {@link Comparator} is null, * optionally reversed. * * @param comparator comparator, or null for natural ordering * @param reversed whether to return a reversed {@link Comparator} * @param compared type * @return a non-null {@link Comparator} */ @SuppressWarnings("unchecked") static Comparator getComparator(Comparator comparator, boolean reversed) { if (comparator == null) comparator = (Comparator)Comparator.naturalOrder(); return reversed ? comparator.reversed() : comparator; } /** * Return the given {@link Comparator}, or natural order {@link Comparator} if the given {@link Comparator} is null. * * @param comparator comparator, or null for natural ordering * @param compared type * @return a non-null {@link Comparator} */ @SuppressWarnings("unchecked") static Comparator comparatorOrNatural(Comparator comparator) { return NavigableSets.getComparator(comparator, false); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy