1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in compliance with the License. You may obtain a copy of the License at
6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0
8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software distributed under the License
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * or implied. See the License for the specific language governing permissions and limitations under
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the License.
13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect;
16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport static com.google.common.base.Preconditions.checkArgument;
18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
22090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.IOException;
23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.ObjectInputStream;
24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.ObjectOutputStream;
25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.EnumMap;
26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Iterator;
27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/**
29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Multiset implementation backed by an {@link EnumMap}.
30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Jared Levy
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library)
33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class EnumMultiset<E extends Enum<E>> extends AbstractMapBasedMultiset<E> {
36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /** Creates an empty {@code EnumMultiset}. */
37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <E extends Enum<E>> EnumMultiset<E> create(Class<E> type) {
38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new EnumMultiset<E>(type);
39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Creates a new {@code EnumMultiset} containing the specified elements.
43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>This implementation is highly efficient when {@code elements} is itself a {@link
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Multiset}.
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param elements the elements that the multiset should contain
48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws IllegalArgumentException if {@code elements} is empty
49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E extends Enum<E>> EnumMultiset<E> create(Iterable<E> elements) {
51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Iterator<E> iterator = elements.iterator();
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkArgument(iterator.hasNext(), "EnumMultiset constructor passed empty Iterable");
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMultiset<E> multiset = new EnumMultiset<E>(iterator.next().getDeclaringClass());
54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Iterables.addAll(multiset, elements);
55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return multiset;
56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private transient Class<E> type;
59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /** Creates an empty {@code EnumMultiset}. */
61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private EnumMultiset(Class<E> type) {
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    super(WellBehavedMap.wrap(new EnumMap<E, Count>(type)));
63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    this.type = type;
64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("java.io.ObjectOutputStream")
67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private void writeObject(ObjectOutputStream stream) throws IOException {
68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    stream.defaultWriteObject();
69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    stream.writeObject(type);
70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Serialization.writeMultiset(this, stream);
71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @serialData the {@code Class<E>} for the enum type, the number of distinct
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *             elements, the first element, its count, the second element, its
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *             count, and so on
77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("java.io.ObjectInputStream")
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    stream.defaultReadObject();
81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @SuppressWarnings("unchecked") // reading data stored by writeObject
82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Class<E> localType = (Class<E>) stream.readObject();
83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    type = localType;
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    setBackingMap(WellBehavedMap.wrap(new EnumMap<E, Count>(type)));
85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Serialization.populateMultiset(this, stream);
86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Not needed in emulated source")
89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static final long serialVersionUID = 0;
90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson}
91