151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Map.Entry; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A specialized {@link Map} implementation for use with enum type keys. All 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the keys in an enum map must come from a single enum type that is 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified, explicitly or implicitly, when the map is created. Enum maps 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are represented internally as arrays. This representation is extremely 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * compact and efficient. 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Enum maps are maintained in the <i>natural order</i> of their keys 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (the order in which the enum constants are declared). This is reflected 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in the iterators returned by the collections views ({@link #keySet()}, 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #entrySet()}, and {@link #values()}). 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Iterators returned by the collection views are <i>weakly consistent</i>: 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * they will never throw {@link ConcurrentModificationException} and they may 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or may not show the effects of any modifications to the map that occur while 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the iteration is in progress. 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Null keys are not permitted. Attempts to insert a null key will 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throw {@link NullPointerException}. Attempts to test for the 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * presence of a null key or to remove one will, however, function properly. 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Null values are permitted. 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>Like most collection implementations <tt>EnumMap</tt> is not 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * synchronized. If multiple threads access an enum map concurrently, and at 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * least one of the threads modifies the map, it should be synchronized 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * externally. This is typically accomplished by synchronizing on some 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object that naturally encapsulates the enum map. If no such object exists, 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the map should be "wrapped" using the {@link Collections#synchronizedMap} 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method. This is best done at creation time, to prevent accidental 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unsynchronized access: 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Map<EnumKey, V> m 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * = Collections.synchronizedMap(new EnumMap<EnumKey, V>(...)); 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Implementation note: All basic operations execute in constant time. 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * They are likely (though not guaranteed) to be faster than their 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link HashMap} counterparts. 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>This class is a member of the 72d2449bb576ad1e3a3877364e5e1ae28625f69e35Yi Kong * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html"> 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Java Collections Framework</a>. 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Josh Bloch 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see EnumSet 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.5 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V> 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implements java.io.Serializable, Cloneable 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The <tt>Class</tt> object for the enum type of all the keys of this map. 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Class<K> keyType; 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * All of the values comprising K. (Cached for performance.) 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private transient K[] keyUniverse; 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Array representation of this map. The ith element is the value 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to which universe[i] is currently mapped, or null if it isn't 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * mapped to anything, or NULL if it's mapped to null. 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private transient Object[] vals; 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The number of mappings in this map. 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private transient int size = 0; 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Distinguished non-null value for representing null values. 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final Object NULL = new Object() { 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int hashCode() { 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toString() { 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return "java.util.EnumMap.NULL"; 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object maskNull(Object value) { 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (value == null ? NULL : value); 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private V unmaskNull(Object value) { 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (V) (value == NULL ? null : value); 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0]; 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates an empty enum map with the specified key type. 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param keyType the class object of the key type for this enum map 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if <tt>keyType</tt> is null 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public EnumMap(Class<K> keyType) { 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.keyType = keyType; 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyUniverse = getKeyUniverse(keyType); 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals = new Object[keyUniverse.length]; 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates an enum map with the same key type as the specified enum 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * map, initially containing the same mappings (if any). 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param m the enum map from which to initialize this enum map 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if <tt>m</tt> is null 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public EnumMap(EnumMap<K, ? extends V> m) { 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyType = m.keyType; 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyUniverse = m.keyUniverse; 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals = m.vals.clone(); 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size = m.size; 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates an enum map initialized from the specified map. If the 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified map is an <tt>EnumMap</tt> instance, this constructor behaves 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * identically to {@link #EnumMap(EnumMap)}. Otherwise, the specified map 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * must contain at least one mapping (in order to determine the new 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * enum map's key type). 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param m the map from which to initialize this enum map 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if <tt>m</tt> is not an 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tt>EnumMap</tt> instance and contains no mappings 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if <tt>m</tt> is null 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public EnumMap(Map<K, ? extends V> m) { 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (m instanceof EnumMap) { 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski EnumMap<K, ? extends V> em = (EnumMap<K, ? extends V>) m; 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyType = em.keyType; 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyUniverse = em.keyUniverse; 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals = em.vals.clone(); 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size = em.size; 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (m.isEmpty()) 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Specified map is empty"); 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyType = m.keySet().iterator().next().getDeclaringClass(); 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyUniverse = getKeyUniverse(keyType); 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals = new Object[keyUniverse.length]; 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski putAll(m); 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Query Operations 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the number of key-value mappings in this map. 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the number of key-value mappings in this map 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int size() { 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size; 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns <tt>true</tt> if this map maps one or more keys to the 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified value. 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param value the value whose presence in this map is to be tested 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return <tt>true</tt> if this map maps one or more keys to this value 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean containsValue(Object value) { 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = maskNull(value); 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (Object val : vals) 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value.equals(val)) 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns <tt>true</tt> if this map contains a mapping for the specified 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * key. 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param key the key whose presence in this map is to be tested 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return <tt>true</tt> if this map contains a mapping for the specified 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * key 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean containsKey(Object key) { 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isValidKey(key) && vals[((Enum)key).ordinal()] != null; 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean containsMapping(Object key, Object value) { 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isValidKey(key) && 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maskNull(value).equals(vals[((Enum)key).ordinal()]); 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the value to which the specified key is mapped, 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or {@code null} if this map contains no mapping for the key. 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>More formally, if this map contains a mapping from a key 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@code k} to a value {@code v} such that {@code (key == k)}, 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * then this method returns {@code v}; otherwise it returns 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@code null}. (There can be at most one such mapping.) 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>A return value of {@code null} does not <i>necessarily</i> 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * indicate that the map contains no mapping for the key; it's also 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * possible that the map explicitly maps the key to {@code null}. 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The {@link #containsKey containsKey} operation may be used to 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * distinguish these two cases. 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public V get(Object key) { 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (isValidKey(key) ? 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unmaskNull(vals[((Enum)key).ordinal()]) : null); 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Modification Operations 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Associates the specified value with the specified key in this map. 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the map previously contained a mapping for this key, the old 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * value is replaced. 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param key the key with which the specified value is to be associated 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param value the value to be associated with the specified key 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the previous value associated with specified key, or 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tt>null</tt> if there was no mapping for key. (A <tt>null</tt> 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return can also indicate that the map previously associated 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tt>null</tt> with the specified key.) 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if the specified key is null 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public V put(K key, V value) { 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski typeCheck(key); 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = key.ordinal(); 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object oldValue = vals[index]; 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals[index] = maskNull(value); 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (oldValue == null) 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size++; 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return unmaskNull(oldValue); 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Removes the mapping for this key from this map if present. 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param key the key whose mapping is to be removed from the map 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the previous value associated with specified key, or 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tt>null</tt> if there was no entry for key. (A <tt>null</tt> 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return can also indicate that the map previously associated 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tt>null</tt> with the specified key.) 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public V remove(Object key) { 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isValidKey(key)) 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = ((Enum)key).ordinal(); 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object oldValue = vals[index]; 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals[index] = null; 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (oldValue != null) 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size--; 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return unmaskNull(oldValue); 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean removeMapping(Object key, Object value) { 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isValidKey(key)) 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = ((Enum)key).ordinal(); 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (maskNull(value).equals(vals[index])) { 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals[index] = null; 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size--; 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true if key is of the proper type to be a key in this 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * enum map. 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isValidKey(Object key) { 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (key == null) 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Cheaper than instanceof Enum followed by getDeclaringClass 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class keyClass = key.getClass(); 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return keyClass == keyType || keyClass.getSuperclass() == keyType; 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Bulk Operations 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copies all of the mappings from the specified map to this map. 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * These mappings will replace any mappings that this map had for 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * any of the keys currently in the specified map. 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param m the mappings to be stored in this map 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException the specified map is null, or if 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * one or more keys in the specified map are null 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void putAll(Map<? extends K, ? extends V> m) { 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (m instanceof EnumMap) { 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski EnumMap<? extends K, ? extends V> em = 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (EnumMap<? extends K, ? extends V>)m; 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (em.keyType != keyType) { 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (em.isEmpty()) 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClassCastException(em.keyType + " != " + keyType); 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < keyUniverse.length; i++) { 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object emValue = em.vals[i]; 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (emValue != null) { 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (vals[i] == null) 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size++; 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals[i] = emValue; 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super.putAll(m); 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Removes all mappings from this map. 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void clear() { 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Arrays.fill(vals, null); 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size = 0; 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Views 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This field is initialized to contain an instance of the entry set 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * view the first time this view is requested. The view is stateless, 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * so there's no reason to create more than one. 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private transient Set<Map.Entry<K,V>> entrySet = null; 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a {@link Set} view of the keys contained in this map. 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The returned set obeys the general contract outlined in 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link Map#keySet()}. The set's iterator will return the keys 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in their natural order (the order in which the enum constants 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are declared). 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a set view of the keys contained in this enum map 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Set<K> keySet() { 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Set<K> ks = keySet; 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ks != null) 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ks; 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return keySet = new KeySet(); 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class KeySet extends AbstractSet<K> { 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Iterator<K> iterator() { 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new KeyIterator(); 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int size() { 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size; 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean contains(Object o) { 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return containsKey(o); 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean remove(Object o) { 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldSize = size; 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski EnumMap.this.remove(o); 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size != oldSize; 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void clear() { 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski EnumMap.this.clear(); 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a {@link Collection} view of the values contained in this map. 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The returned collection obeys the general contract outlined in 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link Map#values()}. The collection's iterator will return the 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * values in the order their corresponding keys appear in map, 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * which is their natural order (the order in which the enum constants 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are declared). 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a collection view of the values contained in this map 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Collection<V> values() { 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Collection<V> vs = values; 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (vs != null) 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return vs; 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return values = new Values(); 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class Values extends AbstractCollection<V> { 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Iterator<V> iterator() { 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new ValueIterator(); 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int size() { 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size; 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean contains(Object o) { 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return containsValue(o); 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean remove(Object o) { 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski o = maskNull(o); 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < vals.length; i++) { 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (o.equals(vals[i])) { 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals[i] = null; 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size--; 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void clear() { 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski EnumMap.this.clear(); 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a {@link Set} view of the mappings contained in this map. 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The returned set obeys the general contract outlined in 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link Map#keySet()}. The set's iterator will return the 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * mappings in the order their keys appear in map, which is their 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * natural order (the order in which the enum constants are declared). 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a set view of the mappings contained in this enum map 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Set<Map.Entry<K,V>> entrySet() { 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Set<Map.Entry<K,V>> es = entrySet; 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (es != null) 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return es; 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return entrySet = new EntrySet(); 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class EntrySet extends AbstractSet<Map.Entry<K,V>> { 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Iterator<Map.Entry<K,V>> iterator() { 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new EntryIterator(); 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean contains(Object o) { 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(o instanceof Map.Entry)) 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map.Entry entry = (Map.Entry)o; 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return containsMapping(entry.getKey(), entry.getValue()); 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean remove(Object o) { 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(o instanceof Map.Entry)) 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map.Entry entry = (Map.Entry)o; 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return removeMapping(entry.getKey(), entry.getValue()); 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int size() { 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size; 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void clear() { 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski EnumMap.this.clear(); 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Object[] toArray() { 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fillEntryArray(new Object[size]); 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @SuppressWarnings("unchecked") 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public <T> T[] toArray(T[] a) { 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int size = size(); 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (a.length < size) 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski a = (T[])java.lang.reflect.Array 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .newInstance(a.getClass().getComponentType(), size); 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (a.length > size) 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski a[size] = null; 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T[]) fillEntryArray(a); 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object[] fillEntryArray(Object[] a) { 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int j = 0; 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < vals.length; i++) 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (vals[i] != null) 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski a[j++] = new AbstractMap.SimpleEntry<>( 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyUniverse[i], unmaskNull(vals[i])); 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return a; 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private abstract class EnumMapIterator<T> implements Iterator<T> { 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lower bound on index of next element to return 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = 0; 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Index of last returned element, or -1 if none 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lastReturnedIndex = -1; 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasNext() { 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (index < vals.length && vals[index] == null) 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski index++; 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return index != vals.length; 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void remove() { 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkLastReturnedIndex(); 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (vals[lastReturnedIndex] != null) { 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals[lastReturnedIndex] = null; 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size--; 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastReturnedIndex = -1; 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void checkLastReturnedIndex() { 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (lastReturnedIndex < 0) 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalStateException(); 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class KeyIterator extends EnumMapIterator<K> { 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public K next() { 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!hasNext()) 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastReturnedIndex = index++; 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return keyUniverse[lastReturnedIndex]; 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class ValueIterator extends EnumMapIterator<V> { 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public V next() { 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!hasNext()) 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastReturnedIndex = index++; 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return unmaskNull(vals[lastReturnedIndex]); 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>> { 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Entry lastReturnedEntry = null; 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Map.Entry<K,V> next() { 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!hasNext()) 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastReturnedEntry = new Entry(index++); 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return lastReturnedEntry; 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void remove() { 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastReturnedIndex = 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index); 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super.remove(); 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastReturnedEntry.index = lastReturnedIndex; 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastReturnedEntry = null; 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class Entry implements Map.Entry<K,V> { 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int index; 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Entry(int index) { 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.index = index; 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public K getKey() { 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkIndexForEntryUse(); 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return keyUniverse[index]; 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public V getValue() { 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkIndexForEntryUse(); 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return unmaskNull(vals[index]); 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public V setValue(V value) { 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkIndexForEntryUse(); 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski V oldValue = unmaskNull(vals[index]); 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals[index] = maskNull(value); 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return oldValue; 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean equals(Object o) { 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (index < 0) 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return o == this; 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(o instanceof Map.Entry)) 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map.Entry e = (Map.Entry)o; 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski V ourValue = unmaskNull(vals[index]); 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object hisValue = e.getValue(); 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (e.getKey() == keyUniverse[index] && 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (ourValue == hisValue || 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (ourValue != null && ourValue.equals(hisValue)))); 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int hashCode() { 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (index < 0) 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return super.hashCode(); 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return entryHashCode(index); 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toString() { 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (index < 0) 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return super.toString(); 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return keyUniverse[index] + "=" 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + unmaskNull(vals[index]); 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void checkIndexForEntryUse() { 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (index < 0) 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalStateException("Entry was removed"); 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Comparison and hashing 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Compares the specified object with this map for equality. Returns 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tt>true</tt> if the given object is also a map and the two maps 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * represent the same mappings, as specified in the {@link 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Map#equals(Object)} contract. 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param o the object to be compared for equality with this map 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return <tt>true</tt> if the specified object is equal to this map 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean equals(Object o) { 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (this == o) 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (o instanceof EnumMap) 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return equals((EnumMap)o); 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(o instanceof Map)) 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map<K,V> m = (Map<K,V>)o; 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (size != m.size()) 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < keyUniverse.length; i++) { 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (null != vals[i]) { 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski K key = keyUniverse[i]; 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski V value = unmaskNull(vals[i]); 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (null == value) { 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!((null == m.get(key)) && m.containsKey(key))) 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!value.equals(m.get(key))) 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean equals(EnumMap em) { 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (em.keyType != keyType) 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return size == 0 && em.size == 0; 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Key types match, compare each value 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < keyUniverse.length; i++) { 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object ourValue = vals[i]; 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object hisValue = em.vals[i]; 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hisValue != ourValue && 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (hisValue == null || !hisValue.equals(ourValue))) 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the hash code value for this map. The hash code of a map is 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * defined to be the sum of the hash codes of each entry in the map. 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int hashCode() { 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int h = 0; 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < keyUniverse.length; i++) { 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (null != vals[i]) { 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski h += entryHashCode(i); 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return h; 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int entryHashCode(int index) { 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (keyUniverse[index].hashCode() ^ vals[index].hashCode()); 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a shallow copy of this enum map. (The values themselves 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are not cloned. 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a shallow copy of this enum map 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public EnumMap<K, V> clone() { 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski EnumMap<K, V> result = null; 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result = (EnumMap<K, V>) super.clone(); 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch(CloneNotSupportedException e) { 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AssertionError(); 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result.vals = result.vals.clone(); 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result.entrySet = null; 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return result; 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Throws an exception if e is not of the correct type for this enum set. 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void typeCheck(K key) { 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class keyClass = key.getClass(); 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keyClass != keyType && keyClass.getSuperclass() != keyType) 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClassCastException(keyClass + " != " + keyType); 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns all of the values comprising K. 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The result is uncloned, cached, and shared by all callers. 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static <K extends Enum<K>> K[] getKeyUniverse(Class<K> keyType) { 750983b2c6ff9ea6d35adf7ab6398dccf870b7e180aPiotr Jastrzebski // Android-changed: Use JavaLangAccess directly instead of going through 751983b2c6ff9ea6d35adf7ab6398dccf870b7e180aPiotr Jastrzebski // SharedSecrets. 752983b2c6ff9ea6d35adf7ab6398dccf870b7e180aPiotr Jastrzebski return JavaLangAccess.getEnumConstantsShared(keyType); 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final long serialVersionUID = 458661240069192865L; 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Save the state of the <tt>EnumMap</tt> instance to a stream (i.e., 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * serialize it). 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serialData The <i>size</i> of the enum map (the number of key-value 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * mappings) is emitted (int), followed by the key (Object) 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and value (Object) for each key-value mapping represented 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by the enum map. 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void writeObject(java.io.ObjectOutputStream s) 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws java.io.IOException 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Write out the key type and any hidden stuff 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.defaultWriteObject(); 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Write out size (number of Mappings) 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.writeInt(size); 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Write out keys and values (alternating) 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int entriesToBeWritten = size; 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; entriesToBeWritten > 0; i++) { 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (null != vals[i]) { 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.writeObject(keyUniverse[i]); 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.writeObject(unmaskNull(vals[i])); 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entriesToBeWritten--; 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reconstitute the <tt>EnumMap</tt> instance from a stream (i.e., 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * deserialize it). 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void readObject(java.io.ObjectInputStream s) 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws java.io.IOException, ClassNotFoundException 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Read in the key type and any hidden stuff 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.defaultReadObject(); 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyUniverse = getKeyUniverse(keyType); 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vals = new Object[keyUniverse.length]; 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Read in size (number of Mappings) 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int size = s.readInt(); 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Read the keys and values, and put the mappings in the HashMap 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < size; i++) { 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski K key = (K) s.readObject(); 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski V value = (V) s.readObject(); 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski put(key, value); 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 810