1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors 3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you may not use this file except in compliance with the License. 6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * You may obtain a copy of the License at 7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See the License for the specific language governing permissions and 14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * limitations under the License. 15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect; 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.HashMap; 27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Map; 28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable; 30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/** 32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * A {@code BiMap} backed by an {@code EnumMap} instance for keys-to-values, and 33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * a {@code HashMap} instance for values-to-keys. Null keys are not permitted, 34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * but null values are. An {@code EnumHashBiMap} and its inverse are both 35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * serializable. 36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Mike Bostock 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library) 39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true) 41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpublic final class EnumHashBiMap<K extends Enum<K>, V> 42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson extends AbstractBiMap<K, V> { 43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private transient Class<K> keyType; 44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns a new, empty {@code EnumHashBiMap} using the specified key type. 47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param keyType the key type 49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public static <K extends Enum<K>, V> EnumHashBiMap<K, V> 51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson create(Class<K> keyType) { 52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return new EnumHashBiMap<K, V>(keyType); 53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Constructs a new bimap with the same mappings as the specified map. If the 57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * specified map is an {@code EnumHashBiMap} or an {@link EnumBiMap}, the new 58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * bimap has the same key type as the input bimap. Otherwise, the specified 59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * map must contain at least one mapping, in order to determine the key type. 60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param map the map whose mappings are to be placed in this map 62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws IllegalArgumentException if map is not an {@code EnumBiMap} or an 63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * {@code EnumHashBiMap} instance and contains no mappings 64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public static <K extends Enum<K>, V> EnumHashBiMap<K, V> 66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson create(Map<K, ? extends V> map) { 67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson EnumHashBiMap<K, V> bimap = create(EnumBiMap.inferKeyType(map)); 68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson bimap.putAll(map); 69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return bimap; 70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private EnumHashBiMap(Class<K> keyType) { 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(WellBehavedMap.wrap( 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new EnumMap<K, V>(keyType)), 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Maps.<V, K>newHashMapWithExpectedSize( 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keyType.getEnumConstants().length)); 77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson this.keyType = keyType; 78090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // Overriding these two methods to show that values may be null (but not keys) 81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public V put(K key, @Nullable V value) { 83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return super.put(key, value); 84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @Override public V forcePut(K key, @Nullable V value) { 87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return super.forcePut(key, value); 88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** Returns the associated key type. */ 91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public Class<K> keyType() { 92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return keyType; 93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @serialData the key class, number of entries, first key, first value, 97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * second key, second value, and so on. 98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private void writeObject(ObjectOutputStream stream) throws IOException { 101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson stream.defaultWriteObject(); 102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson stream.writeObject(keyType); 103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Serialization.writeMap(this, stream); 104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson @SuppressWarnings("unchecked") // reading field populated by writeObject 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private void readObject(ObjectInputStream stream) 109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throws IOException, ClassNotFoundException { 110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson stream.defaultReadObject(); 111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson keyType = (Class<K>) stream.readObject(); 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setDelegates(WellBehavedMap.wrap(new EnumMap<K, V>(keyType)), 113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson new HashMap<V, K>(keyType.getEnumConstants().length * 3 / 2)); 114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Serialization.populateMap(this, stream); 115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("only needed in emulated source.") 118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private static final long serialVersionUID = 0; 119090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 120