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.checkNotNull;
19  
20  import com.google.common.annotations.GwtCompatible;
21  
22  import javax.annotation.Nullable;
23  
24  /**
25   * An implementation of an immutable sorted map with one or more entries.
26   *
27   * @author Louis Wasserman
28   */
29  @GwtCompatible(emulated = true)
30  @SuppressWarnings("serial") // uses writeReplace, not default serialization
31  final class RegularImmutableSortedMap<K, V> extends ImmutableSortedMap<K, V> {
32    private final transient RegularImmutableSortedSet<K> keySet;
33    private final transient ImmutableList<V> valueList;
34  
35    RegularImmutableSortedMap(RegularImmutableSortedSet<K> keySet, ImmutableList<V> valueList) {
36      this.keySet = keySet;
37      this.valueList = valueList;
38    }
39  
40    RegularImmutableSortedMap(
41        RegularImmutableSortedSet<K> keySet,
42        ImmutableList<V> valueList,
43        ImmutableSortedMap<K, V> descendingMap) {
44      super(descendingMap);
45      this.keySet = keySet;
46      this.valueList = valueList;
47    }
48  
49    @Override
50    ImmutableSet<Entry<K, V>> createEntrySet() {
51      return new EntrySet();
52    }
53  
54    private class EntrySet extends ImmutableMapEntrySet<K, V> {
55      @Override
56      public UnmodifiableIterator<Entry<K, V>> iterator() {
57        return asList().iterator();
58      }
59  
60      @Override
61      ImmutableList<Entry<K, V>> createAsList() {
62        return new ImmutableAsList<Entry<K, V>>() {
63          // avoid additional indirection
64          private final ImmutableList<K> keyList = keySet().asList();
65  
66          @Override
67          public Entry<K, V> get(int index) {
68            return Maps.immutableEntry(keyList.get(index), valueList.get(index));
69          }
70  
71          @Override
72          ImmutableCollection<Entry<K, V>> delegateCollection() {
73            return EntrySet.this;
74          }
75        };
76      }
77  
78      @Override
79      ImmutableMap<K, V> map() {
80        return RegularImmutableSortedMap.this;
81      }
82    }
83  
84    @Override
85    public ImmutableSortedSet<K> keySet() {
86      return keySet;
87    }
88  
89    @Override
90    public ImmutableCollection<V> values() {
91      return valueList;
92    }
93  
94    @Override
95    public V get(@Nullable Object key) {
96      int index = keySet.indexOf(key);
97      return (index == -1) ? null : valueList.get(index);
98    }
99  
100   private ImmutableSortedMap<K, V> getSubMap(int fromIndex, int toIndex) {
101     if (fromIndex == 0 && toIndex == size()) {
102       return this;
103     } else if (fromIndex == toIndex) {
104       return emptyMap(comparator());
105     } else {
106       return from(
107           keySet.getSubSet(fromIndex, toIndex),
108           valueList.subList(fromIndex, toIndex));
109     }
110   }
111 
112   @Override
113   public ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive) {
114     return getSubMap(0, keySet.headIndex(checkNotNull(toKey), inclusive));
115   }
116 
117   @Override
118   public ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive) {
119     return getSubMap(keySet.tailIndex(checkNotNull(fromKey), inclusive), size());
120   }
121 
122   @Override
123   ImmutableSortedMap<K, V> createDescendingMap() {
124     return new RegularImmutableSortedMap<K, V>(
125         (RegularImmutableSortedSet<K>) keySet.descendingSet(),
126         valueList.reverse(),
127         this);
128   }
129 
130 }