Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2007 Google Inc.
      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 static com.google.common.base.Preconditions.checkArgument;
     21 
     22 import java.io.IOException;
     23 import java.io.ObjectInputStream;
     24 import java.io.ObjectOutputStream;
     25 import java.util.EnumMap;
     26 import java.util.Iterator;
     27 import java.util.concurrent.atomic.AtomicInteger;
     28 
     29 /**
     30  * Multiset implementation backed by an {@link EnumMap}.
     31  *
     32  * @author Jared Levy
     33  * @since 2010.01.04 <b>stable</b> (imported from Google Collections Library)
     34  */
     35 @GwtCompatible
     36 public final class EnumMultiset<E extends Enum<E>>
     37     extends AbstractMapBasedMultiset<E> {
     38   /** Creates an empty {@code EnumMultiset}. */
     39   public static <E extends Enum<E>> EnumMultiset<E> create(Class<E> type) {
     40     return new EnumMultiset<E>(type);
     41   }
     42 
     43   /**
     44    * Creates a new {@code EnumMultiset} containing the specified elements.
     45    *
     46    * @param elements the elements that the multiset should contain
     47    * @throws IllegalArgumentException if {@code elements} is empty
     48    */
     49   public static <E extends Enum<E>> EnumMultiset<E> create(
     50       Iterable<E> elements) {
     51     Iterator<E> iterator = elements.iterator();
     52     checkArgument(iterator.hasNext(),
     53         "EnumMultiset constructor passed empty Iterable");
     54     EnumMultiset<E> multiset
     55         = new EnumMultiset<E>(iterator.next().getDeclaringClass());
     56     Iterables.addAll(multiset, elements);
     57     return multiset;
     58   }
     59 
     60   private transient Class<E> type;
     61 
     62   /** Creates an empty {@code EnumMultiset}. */
     63   private EnumMultiset(Class<E> type) {
     64     super(new EnumMap<E, AtomicInteger>(type));
     65     this.type = type;
     66   }
     67 
     68   private void writeObject(ObjectOutputStream stream) throws IOException {
     69     stream.defaultWriteObject();
     70     stream.writeObject(type);
     71     Serialization.writeMultiset(this, stream);
     72   }
     73 
     74   /**
     75    * @serialData the {@code Class<E>} for the enum type, the number of distinct
     76    *     elements, the first element, its count, the second element, its count,
     77    *     and so on
     78    */
     79   private void readObject(ObjectInputStream stream)
     80       throws IOException, ClassNotFoundException {
     81     stream.defaultReadObject();
     82     @SuppressWarnings("unchecked") // reading data stored by writeObject
     83     Class<E> localType = (Class<E>) stream.readObject();
     84     type = localType;
     85     setBackingMap(new EnumMap<E, AtomicInteger>(type));
     86     Serialization.populateMultiset(this, stream);
     87   }
     88 
     89   private static final long serialVersionUID = 0;
     90 }
     91