aboutsummaryrefslogtreecommitdiffstats
path: root/guava/src/com/google/common/collect/ImmutableSortedMultiset.java
diff options
context:
space:
mode:
Diffstat (limited to 'guava/src/com/google/common/collect/ImmutableSortedMultiset.java')
-rw-r--r--guava/src/com/google/common/collect/ImmutableSortedMultiset.java162
1 files changed, 95 insertions, 67 deletions
diff --git a/guava/src/com/google/common/collect/ImmutableSortedMultiset.java b/guava/src/com/google/common/collect/ImmutableSortedMultiset.java
index dadcfb5..82f4abe 100644
--- a/guava/src/com/google/common/collect/ImmutableSortedMultiset.java
+++ b/guava/src/com/google/common/collect/ImmutableSortedMultiset.java
@@ -14,13 +14,12 @@
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.Beta;
import com.google.common.annotations.GwtIncompatible;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -62,7 +61,7 @@ import java.util.List;
*
* {(x, y) | x.compareTo(y) == 0}}</pre>
*
- * <b>Warning:</b> Like most multisets, an {@code ImmutableSortedMultiset} will not function
+ * <b>Warning:</b> Like most multisets, an {@code ImmutableSortedMultiset} will not function
* correctly if an element is modified after being placed in the multiset. For this reason, and to
* avoid general confusion, it is strongly recommended to place only immutable objects into this
* collection.
@@ -70,16 +69,10 @@ import java.util.List;
* <p><b>Note:</b> Although this class is not final, it cannot be subclassed as it has no public or
* protected constructors. Thus, instances of this type are guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Louis Wasserman
- * @since 12.0
*/
-@Beta
@GwtIncompatible("hasn't been tested yet")
-public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultisetFauxverideShim<E>
+abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultisetFauxverideShim<E>
implements SortedMultiset<E> {
// TODO(user): GWT compatibility
@@ -100,11 +93,8 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
* Returns an immutable sorted multiset containing a single element.
*/
public static <E extends Comparable<? super E>> ImmutableSortedMultiset<E> of(E element) {
- RegularImmutableSortedSet<E> elementSet =
- (RegularImmutableSortedSet<E>) ImmutableSortedSet.of(element);
- int[] counts = {1};
- long[] cumulativeCounts = {0, 1};
- return new RegularImmutableSortedMultiset<E>(elementSet, counts, cumulativeCounts, 0, 1);
+ return RegularImmutableSortedMultiset.createFromSorted(
+ NATURAL_ORDER, ImmutableList.of(Multisets.immutableEntry(checkNotNull(element), 1)));
}
/**
@@ -161,9 +151,15 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*/
@SuppressWarnings("unchecked")
public static <E extends Comparable<? super E>> ImmutableSortedMultiset<E> of(
- E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) {
+ E e1,
+ E e2,
+ E e3,
+ E e4,
+ E e5,
+ E e6,
+ E... remaining) {
int size = remaining.length + 6;
- List<E> all = Lists.newArrayListWithCapacity(size);
+ List<E> all = new ArrayList<E>(size);
Collections.addAll(all, e1, e2, e3, e4, e5, e6);
Collections.addAll(all, remaining);
return copyOf(Ordering.natural(), all);
@@ -224,7 +220,7 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
// Unsafe, see ImmutableSortedMultisetFauxverideShim.
@SuppressWarnings("unchecked")
Ordering<E> naturalOrder = (Ordering<E>) Ordering.<Comparable>natural();
- return copyOf(naturalOrder, elements);
+ return copyOfInternal(naturalOrder, elements);
}
/**
@@ -236,7 +232,7 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
public static <E> ImmutableSortedMultiset<E> copyOf(
Comparator<? super E> comparator, Iterator<? extends E> elements) {
checkNotNull(comparator);
- return new Builder<E>(comparator).addAll(elements).build();
+ return copyOfInternal(comparator, elements);
}
/**
@@ -251,21 +247,8 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*/
public static <E> ImmutableSortedMultiset<E> copyOf(
Comparator<? super E> comparator, Iterable<? extends E> elements) {
- if (elements instanceof ImmutableSortedMultiset) {
- @SuppressWarnings("unchecked") // immutable collections are always safe for covariant casts
- ImmutableSortedMultiset<E> multiset = (ImmutableSortedMultiset<E>) elements;
- if (comparator.equals(multiset.comparator())) {
- if (multiset.isPartialView()) {
- return copyOfSortedEntries(comparator, multiset.entrySet().asList());
- } else {
- return multiset;
- }
- }
- }
- elements = Lists.newArrayList(elements); // defensive copy
- TreeMultiset<E> sortedCopy = TreeMultiset.create(checkNotNull(comparator));
- Iterables.addAll(sortedCopy, elements);
- return copyOfSortedEntries(comparator, sortedCopy.entrySet());
+ checkNotNull(comparator);
+ return copyOfInternal(comparator, elements);
}
/**
@@ -282,29 +265,50 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*
* @throws NullPointerException if {@code sortedMultiset} or any of its elements is null
*/
+ @SuppressWarnings("unchecked")
public static <E> ImmutableSortedMultiset<E> copyOfSorted(SortedMultiset<E> sortedMultiset) {
- return copyOfSortedEntries(sortedMultiset.comparator(),
- Lists.newArrayList(sortedMultiset.entrySet()));
+ Comparator<? super E> comparator = sortedMultiset.comparator();
+ if (comparator == null) {
+ comparator = (Comparator<? super E>) NATURAL_ORDER;
+ }
+ return copyOfInternal(comparator, sortedMultiset);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <E> ImmutableSortedMultiset<E> copyOfInternal(
+ Comparator<? super E> comparator, Iterable<? extends E> iterable) {
+ if (SortedIterables.hasSameComparator(comparator, iterable)
+ && iterable instanceof ImmutableSortedMultiset<?>) {
+ ImmutableSortedMultiset<E> multiset = (ImmutableSortedMultiset<E>) iterable;
+ if (!multiset.isPartialView()) {
+ return (ImmutableSortedMultiset<E>) iterable;
+ }
+ }
+ ImmutableList<Entry<E>> entries =
+ (ImmutableList) ImmutableList.copyOf(SortedIterables.sortedCounts(comparator, iterable));
+ if (entries.isEmpty()) {
+ return emptyMultiset(comparator);
+ }
+ verifyEntries(entries);
+ return RegularImmutableSortedMultiset.createFromSorted(comparator, entries);
}
- private static <E> ImmutableSortedMultiset<E> copyOfSortedEntries(
- Comparator<? super E> comparator, Collection<Entry<E>> entries) {
+ private static <E> ImmutableSortedMultiset<E> copyOfInternal(
+ Comparator<? super E> comparator, Iterator<? extends E> iterator) {
+ @SuppressWarnings("unchecked") // We can safely cast from IL<Entry<? extends E>> to IL<Entry<E>>
+ ImmutableList<Entry<E>> entries =
+ (ImmutableList) ImmutableList.copyOf(SortedIterables.sortedCounts(comparator, iterator));
if (entries.isEmpty()) {
return emptyMultiset(comparator);
}
- ImmutableList.Builder<E> elementsBuilder = new ImmutableList.Builder<E>(entries.size());
- int[] counts = new int[entries.size()];
- long[] cumulativeCounts = new long[entries.size() + 1];
- int i = 0;
+ verifyEntries(entries);
+ return RegularImmutableSortedMultiset.createFromSorted(comparator, entries);
+ }
+
+ private static <E> void verifyEntries(Collection<Entry<E>> entries) {
for (Entry<E> entry : entries) {
- elementsBuilder.add(entry.getElement());
- counts[i] = entry.getCount();
- cumulativeCounts[i + 1] = cumulativeCounts[i] + counts[i];
- i++;
+ checkNotNull(entry.getElement());
}
- return new RegularImmutableSortedMultiset<E>(
- new RegularImmutableSortedSet<E>(elementsBuilder.build(), comparator),
- counts, cumulativeCounts, 0, entries.size());
}
@SuppressWarnings("unchecked")
@@ -315,15 +319,49 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
return new EmptyImmutableSortedMultiset<E>(comparator);
}
- ImmutableSortedMultiset() {}
+ private final transient Comparator<? super E> comparator;
+
+ ImmutableSortedMultiset(Comparator<? super E> comparator) {
+ this.comparator = checkNotNull(comparator);
+ }
@Override
- public final Comparator<? super E> comparator() {
- return elementSet().comparator();
+ public Comparator<? super E> comparator() {
+ return comparator;
}
+ // Pretend the comparator can compare anything. If it turns out it can't
+ // compare two elements, it'll throw a CCE. Only methods that are specified to
+ // throw CCE should call this.
+ @SuppressWarnings("unchecked")
+ Comparator<Object> unsafeComparator() {
+ return (Comparator<Object>) comparator;
+ }
+
+ private transient Comparator<? super E> reverseComparator;
+
+ Comparator<? super E> reverseComparator() {
+ Comparator<? super E> result = reverseComparator;
+ if (result == null) {
+ return reverseComparator = Ordering.from(comparator).<E>reverse();
+ }
+ return result;
+ }
+
+ private transient ImmutableSortedSet<E> elementSet;
+
@Override
- public abstract ImmutableSortedSet<E> elementSet();
+ public ImmutableSortedSet<E> elementSet() {
+ ImmutableSortedSet<E> result = elementSet;
+ if (result == null) {
+ return elementSet = createElementSet();
+ }
+ return result;
+ }
+
+ abstract ImmutableSortedSet<E> createElementSet();
+
+ abstract ImmutableSortedSet<E> createDescendingElementSet();
transient ImmutableSortedMultiset<E> descendingMultiset;
@@ -336,15 +374,13 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
return result;
}
+ abstract UnmodifiableIterator<Entry<E>> descendingEntryIterator();
+
/**
* {@inheritDoc}
*
* <p>This implementation is guaranteed to throw an {@link UnsupportedOperationException}.
- *
- * @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final Entry<E> pollFirstEntry() {
throw new UnsupportedOperationException();
@@ -354,13 +390,9 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
* {@inheritDoc}
*
* <p>This implementation is guaranteed to throw an {@link UnsupportedOperationException}.
- *
- * @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
- public final Entry<E> pollLastEntry() {
+ public Entry<E> pollLastEntry() {
throw new UnsupportedOperationException();
}
@@ -370,8 +402,6 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
@Override
public ImmutableSortedMultiset<E> subMultiset(
E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) {
- checkArgument(comparator().compare(lowerBound, upperBound) <= 0,
- "Expected lowerBound <= upperBound but %s > %s", lowerBound, upperBound);
return tailMultiset(lowerBound, lowerBoundType).headMultiset(upperBound, upperBoundType);
}
@@ -432,8 +462,6 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*
* Builder instances can be reused; it is safe to call {@link #build} multiple times to build
* multiple multisets in series.
- *
- * @since 12.0
*/
public static class Builder<E> extends ImmutableMultiset.Builder<E> {
private final Comparator<? super E> comparator;
@@ -538,7 +566,7 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*/
@Override
public ImmutableSortedMultiset<E> build() {
- return copyOfSorted((SortedMultiset<E>) contents);
+ return copyOf(comparator, contents);
}
}