View Javadoc
1   /*
2    * Copyright (C) 2012 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.google.common.collect;
17  
18  import static com.google.common.base.Preconditions.checkArgument;
19  
20  import com.google.common.annotations.GwtCompatible;
21  import com.google.common.collect.ImmutableMap.IteratorBasedImmutableMap;
22  import java.io.Serializable;
23  import java.util.EnumMap;
24  import java.util.Spliterator;
25  import java.util.function.BiConsumer;
26  import javax.annotation.Nullable;
27  
28  /**
29   * Implementation of {@link ImmutableMap} backed by a non-empty {@link
30   * java.util.EnumMap}.
31   *
32   * @author Louis Wasserman
33   */
34  @GwtCompatible(serializable = true, emulated = true)
35  @SuppressWarnings("serial") // we're overriding default serialization
36  final class ImmutableEnumMap<K extends Enum<K>, V> extends IteratorBasedImmutableMap<K, V> {
37    static <K extends Enum<K>, V> ImmutableMap<K, V> asImmutable(EnumMap<K, V> map) {
38      switch (map.size()) {
39        case 0:
40          return ImmutableMap.of();
41        case 1:
42          Entry<K, V> entry = Iterables.getOnlyElement(map.entrySet());
43          return ImmutableMap.of(entry.getKey(), entry.getValue());
44        default:
45          return new ImmutableEnumMap<>(map);
46      }
47    }
48  
49    private final transient EnumMap<K, V> delegate;
50  
51    private ImmutableEnumMap(EnumMap<K, V> delegate) {
52      this.delegate = delegate;
53      checkArgument(!delegate.isEmpty());
54    }
55  
56    @Override
57    UnmodifiableIterator<K> keyIterator() {
58      return Iterators.unmodifiableIterator(delegate.keySet().iterator());
59    }
60  
61    @Override
62    Spliterator<K> keySpliterator() {
63      return delegate.keySet().spliterator();
64    }
65  
66    @Override
67    public int size() {
68      return delegate.size();
69    }
70  
71    @Override
72    public boolean containsKey(@Nullable Object key) {
73      return delegate.containsKey(key);
74    }
75  
76    @Override
77    public V get(Object key) {
78      return delegate.get(key);
79    }
80  
81    @Override
82    public boolean equals(Object object) {
83      if (object == this) {
84        return true;
85      }
86      if (object instanceof ImmutableEnumMap) {
87        object = ((ImmutableEnumMap<?, ?>) object).delegate;
88      }
89      return delegate.equals(object);
90    }
91  
92    @Override
93    UnmodifiableIterator<Entry<K, V>> entryIterator() {
94      return Maps.unmodifiableEntryIterator(delegate.entrySet().iterator());
95    }
96  
97    @Override
98    Spliterator<Entry<K, V>> entrySpliterator() {
99      return CollectSpliterators.map(delegate.entrySet().spliterator(), Maps::unmodifiableEntry);
100   }
101   
102   @Override public void forEach(BiConsumer<? super K, ? super V> action) {
103     delegate.forEach(action);
104   }
105 
106   @Override
107   boolean isPartialView() {
108     return false;
109   }
110 
111   // All callers of the constructor are restricted to <K extends Enum<K>>.
112   @Override
113   Object writeReplace() {
114     return new EnumSerializedForm<>(delegate);
115   }
116 
117   /*
118    * This class is used to serialize ImmutableEnumMap instances.
119    */
120   private static class EnumSerializedForm<K extends Enum<K>, V> implements Serializable {
121     final EnumMap<K, V> delegate;
122 
123     EnumSerializedForm(EnumMap<K, V> delegate) {
124       this.delegate = delegate;
125     }
126 
127     Object readResolve() {
128       return new ImmutableEnumMap<>(delegate);
129     }
130 
131     private static final long serialVersionUID = 0;
132   }
133 }