javadoc.src-html.com.google.common.collect.ImmutableBiMap.html Maven / Gradle / Ivy
The newest version!
001 /*
002 * Copyright (C) 2008 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package com.google.common.collect;
018
019 import com.google.common.annotations.GwtCompatible;
020
021 import java.util.Map;
022
023 import javax.annotation.Nullable;
024
025 /**
026 * An immutable {@link BiMap} with reliable user-specified iteration order. Does
027 * not permit null keys or values. An {@code ImmutableBiMap} and its inverse
028 * have the same iteration ordering.
029 *
030 * <p>An instance of {@code ImmutableBiMap} contains its own data and will
031 * <i>never</i> change. {@code ImmutableBiMap} is convenient for
032 * {@code public static final} maps ("constant maps") and also lets you easily
033 * make a "defensive copy" of a bimap provided to your class by a caller.
034 *
035 * <p><b>Note:</b> Although this class is not final, it cannot be subclassed as
036 * it has no public or protected constructors. Thus, instances of this class are
037 * guaranteed to be immutable.
038 *
039 * @author Jared Levy
040 * @since 2.0 (imported from Google Collections Library)
041 */
042 @GwtCompatible(serializable = true, emulated = true)
043 public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
044 implements BiMap<K, V> {
045
046 private static final ImmutableBiMap<Object, Object> EMPTY_IMMUTABLE_BIMAP
047 = new EmptyBiMap();
048
049 /**
050 * Returns the empty bimap.
051 */
052 // Casting to any type is safe because the set will never hold any elements.
053 @SuppressWarnings("unchecked")
054 public static <K, V> ImmutableBiMap<K, V> of() {
055 return (ImmutableBiMap<K, V>) EMPTY_IMMUTABLE_BIMAP;
056 }
057
058 /**
059 * Returns an immutable bimap containing a single entry.
060 */
061 public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1) {
062 return new RegularImmutableBiMap<K, V>(ImmutableMap.of(k1, v1));
063 }
064
065 /**
066 * Returns an immutable map containing the given entries, in order.
067 *
068 * @throws IllegalArgumentException if duplicate keys or values are added
069 */
070 public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1, K k2, V v2) {
071 return new RegularImmutableBiMap<K, V>(ImmutableMap.of(k1, v1, k2, v2));
072 }
073
074 /**
075 * Returns an immutable map containing the given entries, in order.
076 *
077 * @throws IllegalArgumentException if duplicate keys or values are added
078 */
079 public static <K, V> ImmutableBiMap<K, V> of(
080 K k1, V v1, K k2, V v2, K k3, V v3) {
081 return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
082 k1, v1, k2, v2, k3, v3));
083 }
084
085 /**
086 * Returns an immutable map containing the given entries, in order.
087 *
088 * @throws IllegalArgumentException if duplicate keys or values are added
089 */
090 public static <K, V> ImmutableBiMap<K, V> of(
091 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
092 return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
093 k1, v1, k2, v2, k3, v3, k4, v4));
094 }
095
096 /**
097 * Returns an immutable map containing the given entries, in order.
098 *
099 * @throws IllegalArgumentException if duplicate keys or values are added
100 */
101 public static <K, V> ImmutableBiMap<K, V> of(
102 K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
103 return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
104 k1, v1, k2, v2, k3, v3, k4, v4, k5, v5));
105 }
106
107 // looking for of() with > 5 entries? Use the builder instead.
108
109 /**
110 * Returns a new builder. The generated builder is equivalent to the builder
111 * created by the {@link Builder} constructor.
112 */
113 public static <K, V> Builder<K, V> builder() {
114 return new Builder<K, V>();
115 }
116
117 /**
118 * A builder for creating immutable bimap instances, especially {@code public
119 * static final} bimaps ("constant bimaps"). Example: <pre> {@code
120 *
121 * static final ImmutableBiMap<String, Integer> WORD_TO_INT =
122 * new ImmutableBiMap.Builder<String, Integer>()
123 * .put("one", 1)
124 * .put("two", 2)
125 * .put("three", 3)
126 * .build();}</pre>
127 *
128 * For <i>small</i> immutable bimaps, the {@code ImmutableBiMap.of()} methods
129 * are even more convenient.
130 *
131 * <p>Builder instances can be reused - it is safe to call {@link #build}
132 * multiple times to build multiple bimaps in series. Each bimap is a superset
133 * of the bimaps created before it.
134 *
135 * @since 2.0 (imported from Google Collections Library)
136 */
137 public static final class Builder<K, V> extends ImmutableMap.Builder<K, V> {
138
139 /**
140 * Creates a new builder. The returned builder is equivalent to the builder
141 * generated by {@link ImmutableBiMap#builder}.
142 */
143 public Builder() {}
144
145 /**
146 * Associates {@code key} with {@code value} in the built bimap. Duplicate
147 * keys or values are not allowed, and will cause {@link #build} to fail.
148 */
149 @Override public Builder<K, V> put(K key, V value) {
150 super.put(key, value);
151 return this;
152 }
153
154 /**
155 * Associates all of the given map's keys and values in the built bimap.
156 * Duplicate keys or values are not allowed, and will cause {@link #build}
157 * to fail.
158 *
159 * @throws NullPointerException if any key or value in {@code map} is null
160 */
161 @Override public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
162 super.putAll(map);
163 return this;
164 }
165
166 /**
167 * Returns a newly-created immutable bimap.
168 *
169 * @throws IllegalArgumentException if duplicate keys or values were added
170 */
171 @Override public ImmutableBiMap<K, V> build() {
172 ImmutableMap<K, V> map = super.build();
173 if (map.isEmpty()) {
174 return of();
175 }
176 return new RegularImmutableBiMap<K, V>(map);
177 }
178 }
179
180 /**
181 * Returns an immutable bimap containing the same entries as {@code map}. If
182 * {@code map} somehow contains entries with duplicate keys (for example, if
183 * it is a {@code SortedMap} whose comparator is not <i>consistent with
184 * equals</i>), the results of this method are undefined.
185 *
186 * <p>Despite the method name, this method attempts to avoid actually copying
187 * the data when it is safe to do so. The exact circumstances under which a
188 * copy will or will not be performed are undocumented and subject to change.
189 *
190 * @throws IllegalArgumentException if two keys have the same value
191 * @throws NullPointerException if any key or value in {@code map} is null
192 */
193 public static <K, V> ImmutableBiMap<K, V> copyOf(
194 Map<? extends K, ? extends V> map) {
195 if (map instanceof ImmutableBiMap) {
196 @SuppressWarnings("unchecked") // safe since map is not writable
197 ImmutableBiMap<K, V> bimap = (ImmutableBiMap<K, V>) map;
198 // TODO(user): if we need to make a copy of a BiMap because the
199 // forward map is a view, don't make a copy of the non-view delegate map
200 if (!bimap.isPartialView()) {
201 return bimap;
202 }
203 }
204
205 if (map.isEmpty()) {
206 return of();
207 }
208
209 ImmutableMap<K, V> immutableMap = ImmutableMap.copyOf(map);
210 return new RegularImmutableBiMap<K, V>(immutableMap);
211 }
212
213 ImmutableBiMap() {}
214
215 abstract ImmutableMap<K, V> delegate();
216
217 /**
218 * {@inheritDoc}
219 *
220 * <p>The inverse of an {@code ImmutableBiMap} is another
221 * {@code ImmutableBiMap}.
222 */
223 @Override
224 public abstract ImmutableBiMap<V, K> inverse();
225
226 @Override public boolean containsKey(@Nullable Object key) {
227 return delegate().containsKey(key);
228 }
229
230 @Override public boolean containsValue(@Nullable Object value) {
231 return inverse().containsKey(value);
232 }
233
234 @Override public ImmutableSet<Entry<K, V>> entrySet() {
235 return delegate().entrySet();
236 }
237
238 @Override public V get(@Nullable Object key) {
239 return delegate().get(key);
240 }
241
242 @Override public ImmutableSet<K> keySet() {
243 return delegate().keySet();
244 }
245
246 /**
247 * Returns an immutable set of the values in this map. The values are in the
248 * same order as the parameters used to build this map.
249 */
250 @Override public ImmutableSet<V> values() {
251 return inverse().keySet();
252 }
253
254 /**
255 * Guaranteed to throw an exception and leave the bimap unmodified.
256 *
257 * @throws UnsupportedOperationException always
258 */
259 @Override
260 public V forcePut(K key, V value) {
261 throw new UnsupportedOperationException();
262 }
263
264 @Override public boolean isEmpty() {
265 return delegate().isEmpty();
266 }
267
268 @Override
269 public int size() {
270 return delegate().size();
271 }
272
273 @Override public boolean equals(@Nullable Object object) {
274 return object == this || delegate().equals(object);
275 }
276
277 @Override public int hashCode() {
278 return delegate().hashCode();
279 }
280
281 @Override public String toString() {
282 return delegate().toString();
283 }
284
285 /** Bimap with no mappings. */
286 @SuppressWarnings("serial") // uses writeReplace(), not default serialization
287 static class EmptyBiMap extends ImmutableBiMap<Object, Object> {
288 @Override ImmutableMap<Object, Object> delegate() {
289 return ImmutableMap.of();
290 }
291 @Override public ImmutableBiMap<Object, Object> inverse() {
292 return this;
293 }
294 @Override boolean isPartialView() {
295 return false;
296 }
297 Object readResolve() {
298 return EMPTY_IMMUTABLE_BIMAP; // preserve singleton property
299 }
300 }
301
302 /**
303 * Serialized type for all ImmutableBiMap instances. It captures the logical
304 * contents and they are reconstructed using public factory methods. This
305 * ensures that the implementation types remain as implementation details.
306 *
307 * Since the bimap is immutable, ImmutableBiMap doesn't require special logic
308 * for keeping the bimap and its inverse in sync during serialization, the way
309 * AbstractBiMap does.
310 */
311 private static class SerializedForm extends ImmutableMap.SerializedForm {
312 SerializedForm(ImmutableBiMap<?, ?> bimap) {
313 super(bimap);
314 }
315 @Override Object readResolve() {
316 Builder<Object, Object> builder = new Builder<Object, Object>();
317 return createMap(builder);
318 }
319 private static final long serialVersionUID = 0;
320 }
321
322 @Override Object writeReplace() {
323 return new SerializedForm(this);
324 }
325 }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy