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  * @author Kevin Bourrillion
     36  * @author Jared Levy
     37  * @since 2.0 (imported from Google Collections Library)
     38  */
     39 @GwtCompatible(serializable = true, emulated = true)
     40 @SuppressWarnings("serial") // we're overriding default serialization
     41 public final class LinkedHashMultiset<E> extends AbstractMapBasedMultiset<E> {
     42 
     43   /**
     44    * Creates a new, empty {@code LinkedHashMultiset} using the default initial
     45    * capacity.
     46    */
     47   public static <E> LinkedHashMultiset<E> create() {
     48     return new LinkedHashMultiset<E>();
     49   }
     50 
     51   /**
     52    * Creates a new, empty {@code LinkedHashMultiset} with the specified expected
     53    * number of distinct elements.
     54    *
     55    * @param distinctElements the expected number of distinct elements
     56    * @throws IllegalArgumentException if {@code distinctElements} is negative
     57    */
     58   public static <E> LinkedHashMultiset<E> create(int distinctElements) {
     59     return new LinkedHashMultiset<E>(distinctElements);
     60   }
     61 
     62   /**
     63    * Creates a new {@code LinkedHashMultiset} containing the specified elements.
     64    *
     65    * <p>This implementation is highly efficient when {@code elements} is itself
     66    * a {@link Multiset}.
     67    *
     68    * @param elements the elements that the multiset should contain
     69    */
     70   public static <E> LinkedHashMultiset<E> create(
     71       Iterable<? extends E> elements) {
     72     LinkedHashMultiset<E> multiset =
     73         create(Multisets.inferDistinctElements(elements));
     74     Iterables.addAll(multiset, elements);
     75     return multiset;
     76   }
     77 
     78   private LinkedHashMultiset() {
     79     super(new LinkedHashMap<E, Count>());
     80   }
     81 
     82   private LinkedHashMultiset(int distinctElements) {
     83     // Could use newLinkedHashMapWithExpectedSize() if it existed
     84     super(new LinkedHashMap<E, Count>(Maps.capacity(distinctElements)));
     85   }
     86 
     87   /**
     88    * @serialData the number of distinct elements, the first element, its count,
     89    *     the second element, its count, and so on
     90    */
     91   @GwtIncompatible("java.io.ObjectOutputStream")
     92   private void writeObject(ObjectOutputStream stream) throws IOException {
     93     stream.defaultWriteObject();
     94     Serialization.writeMultiset(this, stream);
     95   }
     96 
     97   @GwtIncompatible("java.io.ObjectInputStream")
     98   private void readObject(ObjectInputStream stream)
     99       throws IOException, ClassNotFoundException {
    100     stream.defaultReadObject();
    101     int distinctElements = Serialization.readCount(stream);
    102     setBackingMap(new LinkedHashMap<E, Count>(
    103         Maps.capacity(distinctElements)));
    104     Serialization.populateMultiset(this, stream, distinctElements);
    105   }
    106 
    107   @GwtIncompatible("not needed in emulated source")
    108   private static final long serialVersionUID = 0;
    109 }
    110