Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2007 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.collect;
     18 
     19 import com.google.common.annotations.GwtCompatible;
     20 import com.google.common.annotations.GwtIncompatible;
     21 
     22 import java.io.IOException;
     23 import java.io.ObjectInputStream;
     24 import java.io.ObjectOutputStream;
     25 import java.util.LinkedHashMap;
     26 
     27 /**
     28  * A {@code Multiset} implementation with predictable iteration order. Its
     29  * iterator orders elements according to when the first occurrence of the
     30  * element was added. When the multiset contains multiple instances of an
     31  * element, those instances are consecutive in the iteration order. If all
     32  * occurrences of an element are removed, after which that element is added to
     33  * the multiset, the element will appear at the end of the iteration.
     34  *
     35  * <p>See the Guava User Guide article on <a href=
     36  * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
     37  * {@code Multiset}</a>.
     38  *
     39  * @author Kevin Bourrillion
     40  * @author Jared Levy
     41  * @since 2.0 (imported from Google Collections Library)
     42  */
     43 @GwtCompatible(serializable = true, emulated = true)
     44 @SuppressWarnings("serial") // we're overriding default serialization
     45 public final class LinkedHashMultiset<E> extends AbstractMapBasedMultiset<E> {
     46 
     47   /**
     48    * Creates a new, empty {@code LinkedHashMultiset} using the default initial
     49    * capacity.
     50    */
     51   public static <E> LinkedHashMultiset<E> create() {
     52     return new LinkedHashMultiset<E>();
     53   }
     54 
     55   /**
     56    * Creates a new, empty {@code LinkedHashMultiset} with the specified expected
     57    * number of distinct elements.
     58    *
     59    * @param distinctElements the expected number of distinct elements
     60    * @throws IllegalArgumentException if {@code distinctElements} is negative
     61    */
     62   public static <E> LinkedHashMultiset<E> create(int distinctElements) {
     63     return new LinkedHashMultiset<E>(distinctElements);
     64   }
     65 
     66   /**
     67    * Creates a new {@code LinkedHashMultiset} containing the specified elements.
     68    *
     69    * <p>This implementation is highly efficient when {@code elements} is itself
     70    * a {@link Multiset}.
     71    *
     72    * @param elements the elements that the multiset should contain
     73    */
     74   public static <E> LinkedHashMultiset<E> create(
     75       Iterable<? extends E> elements) {
     76     LinkedHashMultiset<E> multiset =
     77         create(Multisets.inferDistinctElements(elements));
     78     Iterables.addAll(multiset, elements);
     79     return multiset;
     80   }
     81 
     82   private LinkedHashMultiset() {
     83     super(new LinkedHashMap<E, Count>());
     84   }
     85 
     86   private LinkedHashMultiset(int distinctElements) {
     87     // Could use newLinkedHashMapWithExpectedSize() if it existed
     88     super(new LinkedHashMap<E, Count>(Maps.capacity(distinctElements)));
     89   }
     90 
     91   /**
     92    * @serialData the number of distinct elements, the first element, its count,
     93    *     the second element, its count, and so on
     94    */
     95   @GwtIncompatible("java.io.ObjectOutputStream")
     96   private void writeObject(ObjectOutputStream stream) throws IOException {
     97     stream.defaultWriteObject();
     98     Serialization.writeMultiset(this, stream);
     99   }
    100 
    101   @GwtIncompatible("java.io.ObjectInputStream")
    102   private void readObject(ObjectInputStream stream)
    103       throws IOException, ClassNotFoundException {
    104     stream.defaultReadObject();
    105     int distinctElements = Serialization.readCount(stream);
    106     setBackingMap(new LinkedHashMap<E, Count>(
    107         Maps.capacity(distinctElements)));
    108     Serialization.populateMultiset(this, stream, distinctElements);
    109   }
    110 
    111   @GwtIncompatible("not needed in emulated source")
    112   private static final long serialVersionUID = 0;
    113 }
    114