001 /* 002 * Copyright (C) 2007 Google Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package com.google.common.collect; 018 019 import static com.google.common.base.Preconditions.checkArgument; 020 021 import com.google.common.annotations.GwtCompatible; 022 import com.google.common.annotations.GwtIncompatible; 023 024 import java.io.IOException; 025 import java.io.ObjectInputStream; 026 import java.io.ObjectOutputStream; 027 import java.util.EnumMap; 028 import java.util.Iterator; 029 import java.util.concurrent.atomic.AtomicInteger; 030 031 /** 032 * Multiset implementation backed by an {@link EnumMap}. 033 * 034 * @author Jared Levy 035 * @since 2 (imported from Google Collections Library) 036 */ 037 @GwtCompatible(emulated = true) 038 public final class EnumMultiset<E extends Enum<E>> 039 extends AbstractMapBasedMultiset<E> { 040 /** Creates an empty {@code EnumMultiset}. */ 041 public static <E extends Enum<E>> EnumMultiset<E> create(Class<E> type) { 042 return new EnumMultiset<E>(type); 043 } 044 045 /** 046 * Creates a new {@code EnumMultiset} containing the specified elements. 047 * 048 * @param elements the elements that the multiset should contain 049 * @throws IllegalArgumentException if {@code elements} is empty 050 */ 051 public static <E extends Enum<E>> EnumMultiset<E> create( 052 Iterable<E> elements) { 053 Iterator<E> iterator = elements.iterator(); 054 checkArgument(iterator.hasNext(), 055 "EnumMultiset constructor passed empty Iterable"); 056 EnumMultiset<E> multiset 057 = new EnumMultiset<E>(iterator.next().getDeclaringClass()); 058 Iterables.addAll(multiset, elements); 059 return multiset; 060 } 061 062 private transient Class<E> type; 063 064 /** Creates an empty {@code EnumMultiset}. */ 065 private EnumMultiset(Class<E> type) { 066 super(new EnumMap<E, AtomicInteger>(type)); 067 this.type = type; 068 } 069 070 @GwtIncompatible("java.io.ObjectOutputStream") 071 private void writeObject(ObjectOutputStream stream) throws IOException { 072 stream.defaultWriteObject(); 073 stream.writeObject(type); 074 Serialization.writeMultiset(this, stream); 075 } 076 077 /** 078 * @serialData the {@code Class<E>} for the enum type, the number of distinct 079 * elements, the first element, its count, the second element, its count, 080 * and so on 081 */ 082 @GwtIncompatible("java.io.ObjectInputStream") 083 private void readObject(ObjectInputStream stream) 084 throws IOException, ClassNotFoundException { 085 stream.defaultReadObject(); 086 @SuppressWarnings("unchecked") // reading data stored by writeObject 087 Class<E> localType = (Class<E>) stream.readObject(); 088 type = localType; 089 setBackingMap(new EnumMap<E, AtomicInteger>(type)); 090 Serialization.populateMultiset(this, stream); 091 } 092 093 @GwtIncompatible("Not needed in emulated source") 094 private static final long serialVersionUID = 0; 095 }