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