Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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.google.common.collect;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.CollectPreconditions.checkNonnegative;
 import static com.google.common.collect.CollectPreconditions.checkRemove;
 
 
 
A multiset which maintains the ordering of its elements, according to either their natural order or an explicit java.util.Comparator. In all cases, this implementation uses java.lang.Comparable.compareTo(java.lang.Object) or java.util.Comparator.compare(java.lang.Object,java.lang.Object) instead of java.lang.Object.equals(java.lang.Object) to determine equivalence of instances.

Warning: The comparison must be consistent with equals as explained by the java.lang.Comparable class specification. Otherwise, the resulting multiset will violate the java.util.Collection contract, which is specified in terms of java.lang.Object.equals(java.lang.Object).

See the Guava User Guide article on Multiset.

Author(s):
Louis Wasserman
Jared Levy
Since:
2.0 (imported from Google Collections Library)
 
 @GwtCompatible(emulated = true)
 public final class TreeMultiset<E> extends AbstractSortedMultiset<E> implements Serializable {

  
Creates a new, empty multiset, sorted according to the elements' natural order. All elements inserted into the multiset must implement the Comparable interface. Furthermore, all such elements must be mutually comparable: e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the multiset. If the user attempts to add an element to the multiset that violates this constraint (for example, the user attempts to add a string element to a set whose elements are integers), the add(Object) call will throw a ClassCastException.

The type specification is <E extends Comparable>, instead of the more specific <E extends Comparable<? super E>>, to support classes defined without generics.

 
   public static <E extends ComparableTreeMultiset<E> create() {
     return new TreeMultiset<E>(Ordering.natural());
   }

  
Creates a new, empty multiset, sorted according to the specified comparator. All elements inserted into the multiset must be mutually comparable by the specified comparator: comparator.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the multiset. If the user attempts to add an element to the multiset that violates this constraint, the add(Object) call will throw a ClassCastException.

Parameters:
comparator the comparator that will be used to sort this multiset. A null value indicates that the elements' natural ordering should be used.
 
   @SuppressWarnings("unchecked")
   public static <E> TreeMultiset<E> create(@Nullable Comparator<? super E> comparator) {
     return (comparator == null)
         ? new TreeMultiset<E>((Comparator) Ordering.natural())
         : new TreeMultiset<E>(comparator);
   }

  
Creates an empty multiset containing the given initial elements, sorted according to the elements' natural order.

This implementation is highly efficient when elements is itself a Multiset.

The type specification is <E extends Comparable>, instead of the more specific <E extends Comparable<? super E>>, to support classes defined without generics.

  public static <E extends ComparableTreeMultiset<E> create(Iterable<? extends E> elements) {
    TreeMultiset<E> multiset = create();
    Iterables.addAll(multisetelements);
    return multiset;
  }
  private final transient Reference<AvlNode<E>> rootReference;
  private final transient GeneralRange<E> range;
  private final transient AvlNode<E> header;
  TreeMultiset(Reference<AvlNode<E>> rootReferenceGeneralRange<E> rangeAvlNode<E> endLink) {
    super(range.comparator());
    this. = rootReference;
    this. = range;
    this. = endLink;
  }
  TreeMultiset(Comparator<? super E> comparator) {
    super(comparator);
    this. = GeneralRange.all(comparator);
    this. = new AvlNode<E>(null, 1);
    this. = new Reference<AvlNode<E>>();
  }

  
A function which can be summed across a subtree.
  private enum Aggregate {
    SIZE {
      @Override
      int nodeAggregate(AvlNode<?> node) {
        return node.elemCount;
      }
      @Override
      long treeAggregate(@Nullable AvlNode<?> root) {
        return (root == null) ? 0 : root.totalCount;
      }
    },
    DISTINCT {
      @Override
      int nodeAggregate(AvlNode<?> node) {
        return 1;
      }
      @Override
      long treeAggregate(@Nullable AvlNode<?> root) {
        return (root == null) ? 0 : root.distinctElements;
      }
    };
    abstract int nodeAggregate(AvlNode<?> node);
    abstract long treeAggregate(@Nullable AvlNode<?> root);
  }
  private long aggregateForEntries(Aggregate aggr) {
    AvlNode<E> root = .get();
    long total = aggr.treeAggregate(root);
    if (.hasLowerBound()) {
      total -= aggregateBelowRange(aggrroot);
    }
    if (.hasUpperBound()) {
      total -= aggregateAboveRange(aggrroot);
    }
    return total;
  }
  private long aggregateBelowRange(Aggregate aggr, @Nullable AvlNode<E> node) {
    if (node == null) {
      return 0;
    }
    int cmp = comparator().compare(.getLowerEndpoint(), node.elem);
    if (cmp < 0) {
      return aggregateBelowRange(aggrnode.left);
    } else if (cmp == 0) {
      switch (.getLowerBoundType()) {
        case :
          return aggr.nodeAggregate(node) + aggr.treeAggregate(node.left);
        case :
          return aggr.treeAggregate(node.left);
        default:
          throw new AssertionError();
      }
    } else {
      return aggr.treeAggregate(node.left) + aggr.nodeAggregate(node)
          + aggregateBelowRange(aggrnode.right);
    }
  }
  private long aggregateAboveRange(Aggregate aggr, @Nullable AvlNode<E> node) {
    if (node == null) {
      return 0;
    }
    int cmp = comparator().compare(.getUpperEndpoint(), node.elem);
    if (cmp > 0) {
      return aggregateAboveRange(aggrnode.right);
    } else if (cmp == 0) {
      switch (.getUpperBoundType()) {
        case :
          return aggr.nodeAggregate(node) + aggr.treeAggregate(node.right);
        case :
          return aggr.treeAggregate(node.right);
        default:
          throw new AssertionError();
      }
    } else {
      return aggr.treeAggregate(node.right) + aggr.nodeAggregate(node)
          + aggregateAboveRange(aggrnode.left);
    }
  }
  public int size() {
  }
  int distinctElements() {
  }
  public int count(@Nullable Object element) {
    try {
      @SuppressWarnings("unchecked")
      E e = (E) element;
      AvlNode<E> root = .get();
      if (!.contains(e) || root == null) {
        return 0;
      }
      return root.count(comparator(), e);
    } catch (ClassCastException e) {
      return 0;
    } catch (NullPointerException e) {
      return 0;
    }
  }
  public int add(@Nullable E elementint occurrences) {
    checkNonnegative(occurrences"occurrences");
    if (occurrences == 0) {
      return count(element);
    }
    checkArgument(.contains(element));
    AvlNode<E> root = .get();
    if (root == null) {
      comparator().compare(elementelement);
      AvlNode<E> newRoot = new AvlNode<E>(elementoccurrences);
      successor(newRoot);
      .checkAndSet(rootnewRoot);
      return 0;
    }
    int[] result = new int[1]; // used as a mutable int reference to hold result
    AvlNode<E> newRoot = root.add(comparator(), elementoccurrencesresult);
    .checkAndSet(rootnewRoot);
    return result[0];
  }
  public int remove(@Nullable Object elementint occurrences) {
    checkNonnegative(occurrences"occurrences");
    if (occurrences == 0) {
      return count(element);
    }
    AvlNode<E> root = .get();
    int[] result = new int[1]; // used as a mutable int reference to hold result
    AvlNode<E> newRoot;
    try {
      @SuppressWarnings("unchecked")
      E e = (E) element;
      if (!.contains(e) || root == null) {
        return 0;
      }
      newRoot = root.remove(comparator(), eoccurrencesresult);
    } catch (ClassCastException e) {
      return 0;
    } catch (NullPointerException e) {
      return 0;
    }
    .checkAndSet(rootnewRoot);
    return result[0];
  }
  public int setCount(@Nullable E elementint count) {
    checkNonnegative(count"count");
    if (!.contains(element)) {
      checkArgument(count == 0);
      return 0;
    }
    AvlNode<E> root = .get();
    if (root == null) {
      if (count > 0) {
        add(elementcount);
      }
      return 0;
    }
    int[] result = new int[1]; // used as a mutable int reference to hold result
    AvlNode<E> newRoot = root.setCount(comparator(), elementcountresult);
    .checkAndSet(rootnewRoot);
    return result[0];
  }
  public boolean setCount(@Nullable E elementint oldCountint newCount) {
    checkNonnegative(newCount"newCount");
    checkNonnegative(oldCount"oldCount");
    checkArgument(.contains(element));
    AvlNode<E> root = .get();
    if (root == null) {
      if (oldCount == 0) {
        if (newCount > 0) {
          add(elementnewCount);
        }
        return true;
      } else {
        return false;
      }
    }
    int[] result = new int[1]; // used as a mutable int reference to hold result
    AvlNode<E> newRoot = root.setCount(comparator(), elementoldCountnewCountresult);
    .checkAndSet(rootnewRoot);
    return result[0] == oldCount;
  }
  private Entry<E> wrapEntry(final AvlNode<E> baseEntry) {
    return new Multisets.AbstractEntry<E>() {
      @Override
      public E getElement() {
        return baseEntry.getElement();
      }
      @Override
      public int getCount() {
        int result = baseEntry.getCount();
        if (result == 0) {
          return count(getElement());
        } else {
          return result;
        }
      }
    };
  }

  
Returns the first node in the tree that is in range.
  @Nullable private AvlNode<E> firstNode() {
    AvlNode<E> root = .get();
    if (root == null) {
      return null;
    }
    AvlNode<E> node;
    if (.hasLowerBound()) {
      E endpoint = .getLowerEndpoint();
      node = .get().ceiling(comparator(), endpoint);
      if (node == null) {
        return null;
      }
      if (.getLowerBoundType() == .
          && comparator().compare(endpointnode.getElement()) == 0) {
        node = node.succ;
      }
    } else {
      node = .;
    }
    return (node ==  || !.contains(node.getElement())) ? null : node;
  }
  @Nullable private AvlNode<E> lastNode() {
    AvlNode<E> root = .get();
    if (root == null) {
      return null;
    }
    AvlNode<E> node;
    if (.hasUpperBound()) {
      E endpoint = .getUpperEndpoint();
      node = .get().floor(comparator(), endpoint);
      if (node == null) {
        return null;
      }
      if (.getUpperBoundType() == .
          && comparator().compare(endpointnode.getElement()) == 0) {
        node = node.pred;
      }
    } else {
      node = .;
    }
    return (node ==  || !.contains(node.getElement())) ? null : node;
  }
    return new Iterator<Entry<E>>() {
      AvlNode<E> current = firstNode();
      Entry<E> prevEntry;
      @Override
      public boolean hasNext() {
        if ( == null) {
          return false;
        } else if (.tooHigh(.getElement())) {
           = null;
          return false;
        } else {
          return true;
        }
      }
      @Override
      public Entry<E> next() {
        if (!hasNext()) {
          throw new NoSuchElementException();
        }
        Entry<E> result = wrapEntry();
         = result;
        if (. == ) {
           = null;
        } else {
           = .;
        }
        return result;
      }
      @Override
      public void remove() {
        checkRemove( != null);
        setCount(.getElement(), 0);
         = null;
      }
    };
  }
    return new Iterator<Entry<E>>() {
      AvlNode<E> current = lastNode();
      Entry<E> prevEntry = null;
      @Override
      public boolean hasNext() {
        if ( == null) {
          return false;
        } else if (.tooLow(.getElement())) {
           = null;
          return false;
        } else {
          return true;
        }
      }
      @Override
      public Entry<E> next() {
        if (!hasNext()) {
          throw new NoSuchElementException();
        }
        Entry<E> result = wrapEntry();
         = result;
        if (. == ) {
           = null;
        } else {
           = .;
        }
        return result;
      }
      @Override
      public void remove() {
        checkRemove( != null);
        setCount(.getElement(), 0);
         = null;
      }
    };
  }
  public SortedMultiset<E> headMultiset(@Nullable E upperBoundBoundType boundType) {
    return new TreeMultiset<E>(.intersect(GeneralRange.upTo(
        comparator(),
        upperBound,
        boundType)), );
  }
  public SortedMultiset<E> tailMultiset(@Nullable E lowerBoundBoundType boundType) {
    return new TreeMultiset<E>(.intersect(GeneralRange.downTo(
        comparator(),
        lowerBound,
        boundType)), );
  }
  static int distinctElements(@Nullable AvlNode<?> node) {
    return (node == null) ? 0 : node.distinctElements;
  }
  private static final class Reference<T> {
    @Nullable private T value;
    @Nullable public T get() {
      return ;
    }
    public void checkAndSet(@Nullable T expected, T newValue) {
      if ( != expected) {
        throw new ConcurrentModificationException();
      }
       = newValue;
    }
  }
  private static final class AvlNode<E> extends Multisets.AbstractEntry<E> {
    @Nullable private final E elem;
    // elemCount is 0 iff this node has been deleted.
    private int elemCount;
    private int distinctElements;
    private long totalCount;
    private int height;
    private AvlNode<E> left;
    private AvlNode<E> right;
    private AvlNode<E> pred;
    private AvlNode<E> succ;
    AvlNode(@Nullable E elemint elemCount) {
      checkArgument(elemCount > 0);
      this. = elem;
      this. = elemCount;
      this. = elemCount;
      this. = 1;
      this. = 1;
      this. = null;
      this. = null;
    }
    public int count(Comparator<? super E> comparator, E e) {
      int cmp = comparator.compare(e);
      if (cmp < 0) {
        return ( == null) ? 0 : .count(comparatore);
      } else if (cmp > 0) {
        return ( == null) ? 0 : .count(comparatore);
      } else {
        return ;
      }
    }
    private AvlNode<E> addRightChild(E eint count) {
       = new AvlNode<E>(ecount);
      successor(this);
       = Math.max(2, );
      ++;
       += count;
      return this;
    }
    private AvlNode<E> addLeftChild(E eint count) {
       = new AvlNode<E>(ecount);
      successor(this);
       = Math.max(2, );
      ++;
       += count;
      return this;
    }
    AvlNode<E> add(Comparator<? super E> comparator, @Nullable E eint countint[] result) {
      /*
       * It speeds things up considerably to unconditionally add count to totalCount here,
       * but that destroys failure atomicity in the case of count overflow. =(
       */
      int cmp = comparator.compare(e);
      if (cmp < 0) {
        AvlNode<E> initLeft = ;
        if (initLeft == null) {
          result[0] = 0;
          return addLeftChild(ecount);
        }
        int initHeight = initLeft.height;
         = initLeft.add(comparatorecountresult);
        if (result[0] == 0) {
          ++;
        }
        this. += count;
        return (. == initHeight) ? this : rebalance();
      } else if (cmp > 0) {
        AvlNode<E> initRight = ;
        if (initRight == null) {
          result[0] = 0;
          return addRightChild(ecount);
        }
        int initHeight = initRight.height;
         = initRight.add(comparatorecountresult);
        if (result[0] == 0) {
          ++;
        }
        this. += count;
        return (. == initHeight) ? this : rebalance();
      }
      // adding count to me!  No rebalance possible.
      result[0] = ;
      long resultCount = (long + count;
      checkArgument(resultCount <= .);
      this. += count;
      this. += count;
      return this;
    }
    AvlNode<E> remove(Comparator<? super E> comparator, @Nullable E eint countint[] result) {
      int cmp = comparator.compare(e);
      if (cmp < 0) {
        AvlNode<E> initLeft = ;
        if (initLeft == null) {
          result[0] = 0;
          return this;
        }
         = initLeft.remove(comparatorecountresult);
        if (result[0] > 0) {
          if (count >= result[0]) {
            this.--;
            this. -= result[0];
          } else {
            this. -= count;
          }
        }
        return (result[0] == 0) ? this : rebalance();
      } else if (cmp > 0) {
        AvlNode<E> initRight = ;
        if (initRight == null) {
          result[0] = 0;
          return this;
        }
         = initRight.remove(comparatorecountresult);
        if (result[0] > 0) {
          if (count >= result[0]) {
            this.--;
            this. -= result[0];
          } else {
            this. -= count;
          }
        }
        return rebalance();
      }
      // removing count from me!
      result[0] = ;
      if (count >= ) {
        return deleteMe();
      } else {
        this. -= count;
        this. -= count;
        return this;
      }
    }
    AvlNode<E> setCount(Comparator<? super E> comparator, @Nullable E eint countint[] result) {
      int cmp = comparator.compare(e);
      if (cmp < 0) {
        AvlNode<E> initLeft = ;
        if (initLeft == null) {
          result[0] = 0;
          return (count > 0) ? addLeftChild(ecount) : this;
        }
         = initLeft.setCount(comparatorecountresult);
        if (count == 0 && result[0] != 0) {
          this.--;
        } else if (count > 0 && result[0] == 0) {
          this.++;
        }
        this. += count - result[0];
        return rebalance();
      } else if (cmp > 0) {
        AvlNode<E> initRight = ;
        if (initRight == null) {
          result[0] = 0;
          return (count > 0) ? addRightChild(ecount) : this;
        }
         = initRight.setCount(comparatorecountresult);
        if (count == 0 && result[0] != 0) {
          this.--;
        } else if (count > 0 && result[0] == 0) {
          this.++;
        }
        this. += count - result[0];
        return rebalance();
      }
      // setting my count
      result[0] = ;
      if (count == 0) {
        return deleteMe();
      }
      this. += count - ;
      this. = count;
      return this;
    }
    AvlNode<E> setCount(
        Comparator<? super E> comparator,
        @Nullable E e,
        int expectedCount,
        int newCount,
        int[] result) {
      int cmp = comparator.compare(e);
      if (cmp < 0) {
        AvlNode<E> initLeft = ;
        if (initLeft == null) {
          result[0] = 0;
          if (expectedCount == 0 && newCount > 0) {
            return addLeftChild(enewCount);
          }
          return this;
        }
         = initLeft.setCount(comparatoreexpectedCountnewCountresult);
        if (result[0] == expectedCount) {
          if (newCount == 0 && result[0] != 0) {
            this.--;
          } else if (newCount > 0 && result[0] == 0) {
            this.++;
          }
          this. += newCount - result[0];
        }
        return rebalance();
      } else if (cmp > 0) {
        AvlNode<E> initRight = ;
        if (initRight == null) {
          result[0] = 0;
          if (expectedCount == 0 && newCount > 0) {
            return addRightChild(enewCount);
          }
          return this;
        }
         = initRight.setCount(comparatoreexpectedCountnewCountresult);
        if (result[0] == expectedCount) {
          if (newCount == 0 && result[0] != 0) {
            this.--;
          } else if (newCount > 0 && result[0] == 0) {
            this.++;
          }
          this. += newCount - result[0];
        }
        return rebalance();
      }
      // setting my count
      result[0] = ;
      if (expectedCount == ) {
        if (newCount == 0) {
          return deleteMe();
        }
        this. += newCount - ;
        this. = newCount;
      }
      return this;
    }
    private AvlNode<E> deleteMe() {
      int oldElemCount = this.;
      this. = 0;
      successor();
      if ( == null) {
        return ;
      } else if ( == null) {
        return ;
      } else if (. >= .) {
        AvlNode<E> newTop = ;
        // newTop is the maximum node in my left subtree
        newTop.left = .removeMax(newTop);
        newTop.right = ;
        newTop.distinctElements =  - 1;
        newTop.totalCount =  - oldElemCount;
        return newTop.rebalance();
      } else {
        AvlNode<E> newTop = ;
        newTop.right = .removeMin(newTop);
        newTop.left = ;
        newTop.distinctElements =  - 1;
        newTop.totalCount =  - oldElemCount;
        return newTop.rebalance();
      }
    }
    // Removes the minimum node from this subtree to be reused elsewhere
    private AvlNode<E> removeMin(AvlNode<E> node) {
      if ( == null) {
        return ;
      } else {
         = .removeMin(node);
        --;
         -= node.elemCount;
        return rebalance();
      }
    }
    // Removes the maximum node from this subtree to be reused elsewhere
    private AvlNode<E> removeMax(AvlNode<E> node) {
      if ( == null) {
        return ;
      } else {
         = .removeMax(node);
        --;
         -= node.elemCount;
        return rebalance();
      }
    }
    private void recomputeMultiset() {
      this. = 1 + TreeMultiset.distinctElements()
          + TreeMultiset.distinctElements();
      this. =  + totalCount() + totalCount();
    }
    private void recomputeHeight() {
      this. = 1 + Math.max(height(), height());
    }
    private void recompute() {
      recomputeMultiset();
      recomputeHeight();
    }
    private AvlNode<E> rebalance() {
      switch (balanceFactor()) {
        case -2:
          if (.balanceFactor() > 0) {
             = .rotateRight();
          }
          return rotateLeft();
        case 2:
          if (.balanceFactor() < 0) {
             = .rotateLeft();
          }
          return rotateRight();
        default:
          recomputeHeight();
          return this;
      }
    }
    private int balanceFactor() {
      return height() - height();
    }
    private AvlNode<E> rotateLeft() {
      checkState( != null);
      AvlNode<E> newTop = ;
      this. = newTop.left;
      newTop.left = this;
      newTop.totalCount = this.;
      newTop.distinctElements = this.;
      this.recompute();
      newTop.recomputeHeight();
      return newTop;
    }
    private AvlNode<E> rotateRight() {
      checkState( != null);
      AvlNode<E> newTop = ;
      this. = newTop.right;
      newTop.right = this;
      newTop.totalCount = this.;
      newTop.distinctElements = this.;
      this.recompute();
      newTop.recomputeHeight();
      return newTop;
    }
    private static long totalCount(@Nullable AvlNode<?> node) {
      return (node == null) ? 0 : node.totalCount;
    }
    private static int height(@Nullable AvlNode<?> node) {
      return (node == null) ? 0 : node.height;
    }
    @Nullable private AvlNode<E> ceiling(Comparator<? super E> comparator, E e) {
      int cmp = comparator.compare(e);
      if (cmp < 0) {
        return ( == null) ? this : MoreObjects.firstNonNull(.ceiling(comparatore), this);
      } else if (cmp == 0) {
        return this;
      } else {
        return ( == null) ? null : .ceiling(comparatore);
      }
    }
    @Nullable private AvlNode<E> floor(Comparator<? super E> comparator, E e) {
      int cmp = comparator.compare(e);
      if (cmp > 0) {
        return ( == null) ? this : MoreObjects.firstNonNull(.floor(comparatore), this);
      } else if (cmp == 0) {
        return this;
      } else {
        return ( == null) ? null : .floor(comparatore);
      }
    }
    @Override
    public E getElement() {
      return ;
    }
    @Override
    public int getCount() {
      return ;
    }
    @Override
    public String toString() {
      return Multisets.immutableEntry(getElement(), getCount()).toString();
    }
  }
  private static <T> void successor(AvlNode<T> aAvlNode<T> b) {
    a.succ = b;
    b.pred = a;
  }
  private static <T> void successor(AvlNode<T> aAvlNode<T> bAvlNode<T> c) {
    successor(ab);
    successor(bc);
  }
  /*
   * TODO(jlevy): Decide whether entrySet() should return entries with an equals() method that
   * calls the comparator to compare the two keys. If that change is made,
   * AbstractMultiset.equals() can simply check whether two multisets have equal entry sets.
   */

  

SerialData:
the comparator, the number of distinct elements, the first element, its count, the second element, its count, and so on
  @GwtIncompatible("java.io.ObjectOutputStream")
  private void writeObject(ObjectOutputStream streamthrows IOException {
    stream.defaultWriteObject();
    stream.writeObject(elementSet().comparator());
    Serialization.writeMultiset(thisstream);
  }
  @GwtIncompatible("java.io.ObjectInputStream")
  private void readObject(ObjectInputStream streamthrows IOExceptionClassNotFoundException {
    stream.defaultReadObject();
    @SuppressWarnings("unchecked")
    // reading data stored by writeObject
    Comparator<? super E> comparator = (Comparator<? super E>) stream.readObject();
    Serialization.getFieldSetter(AbstractSortedMultiset.class"comparator").set(thiscomparator);
    Serialization.getFieldSetter(TreeMultiset.class"range").set(
        this,
        GeneralRange.all(comparator));
    Serialization.getFieldSetter(TreeMultiset.class"rootReference").set(
        this,
        new Reference<AvlNode<E>>());
    AvlNode<E> header = new AvlNode<E>(null, 1);
    Serialization.getFieldSetter(TreeMultiset.class"header").set(thisheader);
    successor(headerheader);
    Serialization.populateMultiset(thisstream);
  }
  @GwtIncompatible("not needed in emulated source"private static final long serialVersionUID = 1;