1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* Licensed to the Apache Software Foundation (ASF) under one or more
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership.
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License.  You may obtain a copy of the License at
7f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util;
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectInputStream;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Array;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An {@code Map} specialized for use with {@code Enum} types as keys.
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V> implements
29f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        Serializable, Cloneable, Map<K, V> {
30f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
31f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // BEGIN android-changed
32f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // added implements Map<K, V> for apicheck
33f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    // END android-changed
34f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 458661240069192865L;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Class<K> keyType;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    transient Enum[] keys;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    transient Object[] values;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    transient boolean[] hasMapping;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient int mappingsCount;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    transient int enumSize;
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient EnumMapEntrySet<K, V> entrySet = null;
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class Entry<KT extends Enum<KT>, VT> extends
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            MapEntry<KT, VT> {
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final EnumMap<KT, VT> enumMap;
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final int ordinal;
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry(KT theKey, VT theValue, EnumMap<KT, VT> em) {
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(theKey, theValue);
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap = em;
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ordinal = ((Enum) theKey).ordinal();
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        @SuppressWarnings("unchecked")
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean equals(Object object) {
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!enumMap.hasMapping[ordinal]) {
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean isEqual = false;
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (object instanceof Map.Entry) {
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Map.Entry<KT, VT> entry = (Map.Entry<KT, VT>) object;
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Object enumKey = entry.getKey();
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (key.equals(enumKey)) {
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Object theValue = entry.getValue();
75b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                    if (enumMap.values[ordinal] == null) {
76b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                        isEqual = (theValue == null);
77b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                    } else {
78b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                        isEqual = enumMap.values[ordinal].equals(theValue);
79b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                    }
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return isEqual;
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int hashCode() {
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (enumMap.keys[ordinal] == null ? 0 : enumMap.keys[ordinal]
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .hashCode())
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ^ (enumMap.values[ordinal] == null ? 0
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            : enumMap.values[ordinal].hashCode());
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        @SuppressWarnings("unchecked")
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public KT getKey() {
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkEntryStatus();
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (KT) enumMap.keys[ordinal];
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
100f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        @SuppressWarnings("unchecked")
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public VT getValue() {
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkEntryStatus();
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (VT) enumMap.values[ordinal];
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
107f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        @SuppressWarnings("unchecked")
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public VT setValue(VT value) {
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkEntryStatus();
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return enumMap.put((KT) enumMap.keys[ordinal], value);
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public String toString() {
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            StringBuilder result = new StringBuilder(enumMap.keys[ordinal]
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .toString());
118f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            result.append("=");
1197ed4d9e13b7d599a2d6cfdc8cb9e86a8ef0b0dd8Ben Dodson            result.append(enumMap.values[ordinal] == null
1207ed4d9e13b7d599a2d6cfdc8cb9e86a8ef0b0dd8Ben Dodson                    ? "null" : enumMap.values[ordinal].toString());
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return result.toString();
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private void checkEntryStatus() {
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!enumMap.hasMapping[ordinal]) {
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalStateException();
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class EnumMapIterator<E, KT extends Enum<KT>, VT> implements
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Iterator<E> {
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int position = 0;
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int prePosition = -1;
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final EnumMap<KT, VT> enumMap;
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final MapEntry.Type<E, KT, VT> type;
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EnumMapIterator(MapEntry.Type<E, KT, VT> value, EnumMap<KT, VT> em) {
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap = em;
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            type = value;
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean hasNext() {
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int length = enumMap.enumSize;
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (; position < length; position++) {
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (enumMap.hasMapping[position]) {
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return position != length;
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @SuppressWarnings("unchecked")
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public E next() {
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!hasNext()) {
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new NoSuchElementException();
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            prePosition = position++;
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return type.get(new MapEntry(enumMap.keys[prePosition],
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    enumMap.values[prePosition]));
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void remove() {
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkStatus();
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (enumMap.hasMapping[prePosition]) {
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                enumMap.remove(enumMap.keys[prePosition]);
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            prePosition = -1;
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @SuppressWarnings("unchecked")
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public String toString() {
177454684cbffa16064281c824b0c89c2407c48a26cElliott Hughes            if (prePosition == -1) {
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return super.toString();
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return type.get(
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    new MapEntry(enumMap.keys[prePosition],
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            enumMap.values[prePosition])).toString();
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private void checkStatus() {
186454684cbffa16064281c824b0c89c2407c48a26cElliott Hughes            if (prePosition == -1) {
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalStateException();
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class EnumMapKeySet<KT extends Enum<KT>, VT> extends
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            AbstractSet<KT> {
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final EnumMap<KT, VT> enumMap;
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EnumMapKeySet(EnumMap<KT, VT> em) {
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap = em;
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void clear() {
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap.clear();
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean contains(Object object) {
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return enumMap.containsKey(object);
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @SuppressWarnings("unchecked")
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Iterator iterator() {
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new EnumMapIterator<KT, KT, VT>(
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    new MapEntry.Type<KT, KT, VT>() {
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        public KT get(MapEntry<KT, VT> entry) {
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return entry.key;
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }, enumMap);
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @SuppressWarnings("unchecked")
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean remove(Object object) {
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (contains(object)) {
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                enumMap.remove(object);
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return true;
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int size() {
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return enumMap.size();
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class EnumMapValueCollection<KT extends Enum<KT>, VT>
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            extends AbstractCollection<VT> {
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final EnumMap<KT, VT> enumMap;
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EnumMapValueCollection(EnumMap<KT, VT> em) {
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap = em;
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void clear() {
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap.clear();
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean contains(Object object) {
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return enumMap.containsValue(object);
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @SuppressWarnings("unchecked")
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Iterator iterator() {
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new EnumMapIterator<VT, KT, VT>(
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    new MapEntry.Type<VT, KT, VT>() {
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        public VT get(MapEntry<KT, VT> entry) {
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return entry.value;
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }, enumMap);
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean remove(Object object) {
268b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes            if (object == null) {
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < enumMap.enumSize; i++) {
270b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                    if (enumMap.hasMapping[i] && enumMap.values[i] == null) {
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        enumMap.remove(enumMap.keys[i]);
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return true;
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < enumMap.enumSize; i++) {
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (enumMap.hasMapping[i]
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            && object.equals(enumMap.values[i])) {
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        enumMap.remove(enumMap.keys[i]);
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return true;
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int size() {
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return enumMap.size();
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class EnumMapEntryIterator<E, KT extends Enum<KT>, VT>
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            extends EnumMapIterator<E, KT, VT> {
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EnumMapEntryIterator(MapEntry.Type<E, KT, VT> value, EnumMap<KT, VT> em) {
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(value, em);
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
299f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        @SuppressWarnings("unchecked")
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public E next() {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!hasNext()) {
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new NoSuchElementException();
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            prePosition = position++;
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return type.get(new Entry<KT, VT>((KT) enumMap.keys[prePosition],
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    (VT) enumMap.values[prePosition], enumMap));
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class EnumMapEntrySet<KT extends Enum<KT>, VT> extends
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            AbstractSet<Map.Entry<KT, VT>> {
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final EnumMap<KT, VT> enumMap;
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EnumMapEntrySet(EnumMap<KT, VT> em) {
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap = em;
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void clear() {
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap.clear();
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean contains(Object object) {
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean isEqual = false;
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (object instanceof Map.Entry) {
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Object enumKey = ((Map.Entry) object).getKey();
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Object enumValue = ((Map.Entry) object).getValue();
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (enumMap.containsKey(enumKey)) {
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    VT value = enumMap.get(enumKey);
332b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                    if (value == null) {
333b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                        isEqual = enumValue == null;
334b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                    } else {
335b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                        isEqual = value.equals(enumValue);
336b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                    }
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return isEqual;
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Iterator<Map.Entry<KT, VT>> iterator() {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new EnumMapEntryIterator<Map.Entry<KT, VT>, KT, VT>(
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    new MapEntry.Type<Map.Entry<KT, VT>, KT, VT>() {
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        public Map.Entry<KT, VT> get(MapEntry<KT, VT> entry) {
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return entry;
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }, enumMap);
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean remove(Object object) {
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (contains(object)) {
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                enumMap.remove(((Map.Entry) object).getKey());
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return true;
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int size() {
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return enumMap.size();
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object[] toArray() {
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object[] entryArray = new Object[enumMap.size()];
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return toArray(entryArray);
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
372f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        @SuppressWarnings("unchecked")
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object[] toArray(Object[] array) {
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int size = enumMap.size();
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int index = 0;
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object[] entryArray = array;
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (size > array.length) {
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Class<?> clazz = array.getClass().getComponentType();
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entryArray = (Object[]) Array.newInstance(clazz, size);
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Iterator<Map.Entry<KT, VT>> iter = iterator();
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (; index < size; index++) {
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Map.Entry<KT, VT> entry = iter.next();
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entryArray[index] = new MapEntry<KT, VT>(entry.getKey(), entry
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .getValue());
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (index < array.length) {
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entryArray[index] = null;
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return entryArray;
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs an empty {@code EnumMap} using the given key type.
397f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param keyType
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the class object giving the type of the keys used by this {@code EnumMap}.
400f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
401f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code keyType} is {@code null}.
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public EnumMap(Class<K> keyType) {
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        initialization(keyType);
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs an {@code EnumMap} using the same key type as the given {@code EnumMap} and
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * initially containing the same mappings.
410f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param map
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code EnumMap} from which this {@code EnumMap} is initialized.
413f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
414f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code map} is {@code null}.
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public EnumMap(EnumMap<K, ? extends V> map) {
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        initialization(map);
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs an {@code EnumMap} initialized from the given map. If the given map
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is an {@code EnumMap} instance, this constructor behaves in the exactly the same
423f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * way as {@link EnumMap#EnumMap(EnumMap)}}. Otherwise, the given map
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * should contain at least one mapping.
425f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param map
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the map from which this {@code EnumMap} is initialized.
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code map} is not an {@code EnumMap} instance and does not contain
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             any mappings.
431f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
432f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code map} is {@code null}.
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
434f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    @SuppressWarnings("unchecked")
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public EnumMap(Map<K, ? extends V> map) {
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (map instanceof EnumMap) {
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            initialization((EnumMap<K, V>) map);
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
439cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes            if (map.isEmpty()) {
440cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes                throw new IllegalArgumentException("map is empty");
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Iterator<K> iter = map.keySet().iterator();
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            K enumKey = iter.next();
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class clazz = enumKey.getClass();
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (clazz.isEnum()) {
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                initialization(clazz);
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                initialization(clazz.getSuperclass());
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            putAllImpl(map);
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Removes all elements from this {@code EnumMap}, leaving it empty.
456f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #isEmpty()
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #size()
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void clear() {
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Arrays.fill(values, null);
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Arrays.fill(hasMapping, false);
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mappingsCount = 0;
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a shallow copy of this {@code EnumMap}.
469f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a shallow copy of this {@code EnumMap}.
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
472f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    @SuppressWarnings("unchecked")
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public EnumMap<K, V> clone() {
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            EnumMap<K, V> enumMap = (EnumMap<K, V>) super.clone();
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumMap.initialization(this);
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return enumMap;
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (CloneNotSupportedException e) {
480fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes            throw new AssertionError(e);
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this {@code EnumMap} contains the specified key.
486f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key to search for.
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this {@code EnumMap} contains the specified key,
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean containsKey(Object key) {
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isValidKeyType(key)) {
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int keyOrdinal = ((Enum) key).ordinal();
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return hasMapping[keyOrdinal];
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this {@code EnumMap} contains the specified value.
503f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value to search for.
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this {@code EnumMap} contains the specified value,
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean containsValue(Object value) {
511b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (value == null) {
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < enumSize; i++) {
513b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                if (hasMapping[i] && values[i] == null) {
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < enumSize; i++) {
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (hasMapping[i] && value.equals(values[i])) {
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a {@code Set} containing all of the mappings in this {@code EnumMap}. Each mapping is
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * an instance of {@link Map.Entry}. As the {@code Set} is backed by this {@code EnumMap},
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * changes in one will be reflected in the other.
531f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * <p>
532f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * The order of the entries in the set will be the order that the enum keys
533f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * were declared in.
534f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a {@code Set} of the mappings.
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Set<Map.Entry<K, V>> entrySet() {
539b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (entrySet == null) {
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entrySet = new EnumMapEntrySet<K, V>(this);
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return entrySet;
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the argument to the receiver, and returns {@code true} if the
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified {@code Object} is an {@code EnumMap} and both {@code EnumMap}s contain the same mappings.
548f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param object
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code Object} to compare with this {@code EnumMap}.
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return boolean {@code true} if {@code object} is the same as this {@code EnumMap},
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #hashCode()
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #entrySet()
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
556f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    @SuppressWarnings("unchecked")
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object object) {
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this == object) {
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(object instanceof EnumMap)) {
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return super.equals(object);
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EnumMap<K, V> enumMap = (EnumMap<K, V>) object;
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (keyType != enumMap.keyType || size() != enumMap.size()) {
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Arrays.equals(hasMapping, enumMap.hasMapping)
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && Arrays.equals(values, enumMap.values);
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of the mapping with the specified key.
575f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key.
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of the mapping with the specified key, or {@code null}
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         if no mapping for the specified key is found.
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public V get(Object key) {
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isValidKeyType(key)) {
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int keyOrdinal = ((Enum) key).ordinal();
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (V) values[keyOrdinal];
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a set of the keys contained in this {@code EnumMap}. The {@code Set} is backed by
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this {@code EnumMap} so changes to one are reflected in the other. The {@code Set} does not
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * support adding.
595f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * <p>
596f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * The order of the set will be the order that the enum keys were declared
597f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * in.
598f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a {@code Set} of the keys.
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Set<K> keySet() {
603b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (keySet == null) {
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            keySet = new EnumMapKeySet<K, V>(this);
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return keySet;
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Maps the specified key to the specified value.
611f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key.
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value.
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of any previous mapping with the specified key or
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if there was no mapping.
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnsupportedOperationException
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if adding to this map is not supported.
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassCastException
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if the class of the key or value is inappropriate for this
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                map.
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if the key or value cannot be added to this map.
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if the key or value is {@code null} and this {@code EnumMap} does not
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                support {@code null} keys or values.
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public V put(K key, V value) {
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return putImpl(key, value);
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies every mapping in the specified {@code Map} to this {@code EnumMap}.
637f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param map
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code Map} to copy mappings from.
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnsupportedOperationException
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if adding to this {@code EnumMap} is not supported.
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassCastException
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if the class of a key or value is inappropriate for this
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                {@code EnumMap}.
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if a key or value cannot be added to this map.
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if a key or value is {@code null} and this {@code EnumMap} does not
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                support {@code null} keys or values.
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void putAll(Map<? extends K, ? extends V> map) {
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        putAllImpl(map);
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Removes a mapping with the specified key from this {@code EnumMap}.
659f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key of the mapping to remove.
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of the removed mapping or {@code null} if no mapping
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         for the specified key was found.
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnsupportedOperationException
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if removing from this {@code EnumMap} is not supported.
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public V remove(Object key) {
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isValidKeyType(key)) {
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int keyOrdinal = ((Enum) key).ordinal();
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (hasMapping[keyOrdinal]) {
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hasMapping[keyOrdinal] = false;
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mappingsCount--;
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        V oldValue = (V) values[keyOrdinal];
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        values[keyOrdinal] = null;
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return oldValue;
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the number of elements in this {@code EnumMap}.
685f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of elements in this {@code EnumMap}.
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int size() {
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return mappingsCount;
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a {@code Collection} of the values contained in this {@code EnumMap}. The returned
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Collection} complies with the general rule specified in
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link Map#values()}. The {@code Collection}'s {@code Iterator} will return the values
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in the their corresponding keys' natural order (the {@code Enum} constants are
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * declared in this order).
699f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * <p>
700f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * The order of the values in the collection will be the order that their
701f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * corresponding enum keys were declared in.
702f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a collection of the values contained in this {@code EnumMap}.
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Collection<V> values() {
707b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (valuesCollection == null) {
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            valuesCollection = new EnumMapValueCollection<K, V>(this);
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return valuesCollection;
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
713f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    @SuppressWarnings("unchecked")
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readObject(ObjectInputStream stream) throws IOException,
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException {
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        stream.defaultReadObject();
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        initialization(keyType);
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int elementCount = stream.readInt();
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Enum<K> enumKey;
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object value;
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = elementCount; i > 0; i--) {
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enumKey = (Enum<K>) stream.readObject();
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            value = stream.readObject();
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            putImpl((K) enumKey, (V) value);
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void writeObject(ObjectOutputStream stream) throws IOException {
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        stream.defaultWriteObject();
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        stream.writeInt(mappingsCount);
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Iterator<Map.Entry<K, V>> iterator = entrySet().iterator();
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (iterator.hasNext()) {
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Map.Entry<K, V> entry = iterator.next();
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            stream.writeObject(entry.getKey());
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            stream.writeObject(entry.getValue());
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isValidKeyType(Object key) {
740b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (key != null && keyType.isInstance(key)) {
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void initialization(EnumMap enumMap) {
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        keyType = enumMap.keyType;
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        keys = enumMap.keys;
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        enumSize = enumMap.enumSize;
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        values = enumMap.values.clone();
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        hasMapping = enumMap.hasMapping.clone();
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mappingsCount = enumMap.mappingsCount;
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void initialization(Class<K> type) {
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        keyType = type;
758482e8943b4b81534b545260e6da25bb35b93dc5aJesse Wilson        keys = Enum.getSharedConstants(keyType);
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        enumSize = keys.length;
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        values = new Object[enumSize];
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        hasMapping = new boolean[enumSize];
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void putAllImpl(Map map) {
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Iterator iter = map.entrySet().iterator();
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (iter.hasNext()) {
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Map.Entry entry = (Map.Entry) iter.next();
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            putImpl((K) entry.getKey(), (V) entry.getValue());
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private V putImpl(K key, V value) {
775b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (key == null) {
77686acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("key == null");
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
778415c7497ec02890a73eb293f98f69c1f6983389bElliott Hughes        keyType.cast(key); // Called to throw ClassCastException.
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int keyOrdinal = key.ordinal();
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!hasMapping[keyOrdinal]) {
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hasMapping[keyOrdinal] = true;
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mappingsCount++;
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        V oldValue = (V) values[keyOrdinal];
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        values[keyOrdinal] = value;
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return oldValue;
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
790