1 package org.djutils.immutablecollections;
2
3 import java.util.Comparator;
4 import java.util.Map;
5 import java.util.Map.Entry;
6 import java.util.NavigableMap;
7 import java.util.NavigableSet;
8 import java.util.TreeMap;
9 import java.util.TreeSet;
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 public class ImmutableTreeMap<K, V> extends ImmutableAbstractMap<K, V> implements ImmutableNavigableMap<K, V>
25 {
26
27 private static final long serialVersionUID = 20160507L;
28
29
30 private ImmutableSortedSet<K> cachedKeySet = null;
31
32
33 private ImmutableSortedSet<ImmutableEntry<K, V>> cachedEntrySet = null;
34
35
36
37
38 public ImmutableTreeMap(final Map<K, V> sortedMap)
39 {
40 super(new TreeMap<K, V>(sortedMap), Immutable.COPY);
41 }
42
43
44
45
46
47 public ImmutableTreeMap(final NavigableMap<K, V> map, final Immutable copyOrWrap)
48 {
49 super(copyOrWrap == Immutable.COPY ? new TreeMap<K, V>(map) : map, copyOrWrap);
50 }
51
52
53
54
55 public ImmutableTreeMap(final ImmutableAbstractMap<K, V> immutableMap)
56 {
57 super(new TreeMap<K, V>(immutableMap.getUnderlyingMap()), Immutable.COPY);
58 }
59
60
61
62
63
64 public ImmutableTreeMap(final ImmutableTreeMap<K, V> immutableTreeMap, final Immutable copyOrWrap)
65 {
66 super(copyOrWrap == Immutable.COPY ? new TreeMap<K, V>(immutableTreeMap.getUnderlyingMap())
67 : immutableTreeMap.getUnderlyingMap(), copyOrWrap);
68 }
69
70
71 @Override
72 protected final NavigableMap<K, V> getUnderlyingMap()
73 {
74 return (NavigableMap<K, V>) super.getUnderlyingMap();
75 }
76
77
78 @Override
79 public final NavigableMap<K, V> toMap()
80 {
81 return new TreeMap<K, V>(super.getUnderlyingMap());
82 }
83
84
85 @Override
86 public final ImmutableSortedSet<K> keySet()
87 {
88 if (this.cachedKeySet == null)
89 {
90 NavigableSet<K> immutableKeySet = new TreeSet<>(getUnderlyingMap().comparator());
91 immutableKeySet.addAll(getUnderlyingMap().keySet());
92 this.cachedKeySet = new ImmutableTreeSet<>(immutableKeySet, Immutable.WRAP);
93 }
94 return this.cachedKeySet;
95 }
96
97
98 @Override
99 public ImmutableSortedSet<ImmutableEntry<K, V>> entrySet()
100 {
101 if (this.cachedEntrySet == null)
102 {
103 NavigableSet<ImmutableEntry<K, V>> immutableEntrySet = new TreeSet<>(new Comparator<ImmutableEntry<K, V>>()
104 {
105
106 @SuppressWarnings("unchecked")
107 @Override
108 public int compare(final ImmutableEntry<K, V> o1, final ImmutableEntry<K, V> o2)
109 {
110 return ((Comparable<K>) o1.getKey()).compareTo(o2.getKey());
111 }
112
113 });
114 for (Entry<K, V> entry : getUnderlyingMap().entrySet())
115 {
116 immutableEntrySet.add(new ImmutableEntry<>(entry));
117 }
118 this.cachedEntrySet = new ImmutableTreeSet<>(immutableEntrySet, Immutable.WRAP);
119 }
120 return this.cachedEntrySet;
121 }
122
123
124 @Override
125 public ImmutableSortedSet<V> values()
126 {
127 if (this.cachedValues == null)
128 {
129 NavigableSet<V> immutableValues = new TreeSet<>(getUnderlyingMap().values());
130 this.cachedValues = new ImmutableTreeSet<>(immutableValues, Immutable.WRAP);
131 }
132 return (ImmutableNavigableSet<V>) this.cachedValues;
133 }
134
135
136 @Override
137 public final Comparator<? super K> comparator()
138 {
139 return getUnderlyingMap().comparator();
140 }
141
142
143 @Override
144 public final ImmutableSortedMap<K, V> subMap(final K fromKey, final K toKey)
145 {
146 return new ImmutableTreeMap<K, V>(getUnderlyingMap().subMap(fromKey, toKey));
147 }
148
149
150 @Override
151 public final ImmutableSortedMap<K, V> headMap(final K toKey)
152 {
153 return new ImmutableTreeMap<K, V>(getUnderlyingMap().headMap(toKey));
154 }
155
156
157 @Override
158 public final ImmutableSortedMap<K, V> tailMap(final K fromKey)
159 {
160 return new ImmutableTreeMap<K, V>(getUnderlyingMap().tailMap(fromKey));
161 }
162
163
164 @Override
165 public final K firstKey()
166 {
167 return getUnderlyingMap().firstKey();
168 }
169
170
171 @Override
172 public final K lastKey()
173 {
174 return getUnderlyingMap().lastKey();
175 }
176
177
178 @Override
179 public final K lowerKey(final K key)
180 {
181 return getUnderlyingMap().lowerKey(key);
182 }
183
184
185 @Override
186 public final K floorKey(final K key)
187 {
188 return getUnderlyingMap().floorKey(key);
189 }
190
191
192 @Override
193 public final K ceilingKey(final K key)
194 {
195 return getUnderlyingMap().ceilingKey(key);
196 }
197
198
199 @Override
200 public final K higherKey(final K key)
201 {
202 return getUnderlyingMap().higherKey(key);
203 }
204
205
206 @Override
207 public final ImmutableNavigableMap<K, V> descendingMap()
208 {
209 return new ImmutableTreeMap<K, V>(getUnderlyingMap().descendingMap());
210 }
211
212
213 @Override
214 public final ImmutableNavigableMap<K, V> subMap(final K fromKey, final boolean fromInclusive, final K toKey,
215 final boolean toInclusive)
216 {
217 return new ImmutableTreeMap<K, V>(getUnderlyingMap().subMap(fromKey, fromInclusive, toKey, toInclusive));
218 }
219
220
221 @Override
222 public final ImmutableNavigableMap<K, V> headMap(final K toKey, final boolean inclusive)
223 {
224 return new ImmutableTreeMap<K, V>(getUnderlyingMap().headMap(toKey, inclusive));
225 }
226
227
228 @Override
229 public final ImmutableNavigableMap<K, V> tailMap(final K fromKey, final boolean inclusive)
230 {
231 return new ImmutableTreeMap<K, V>(getUnderlyingMap().tailMap(fromKey, inclusive));
232 }
233
234
235 @Override
236 public final String toString()
237 {
238 NavigableMap<K, V> map = getUnderlyingMap();
239 if (null == map)
240 {
241 return "ImmutableTreeMap []";
242 }
243 return "ImmutableTreeMap [" + map.toString() + "]";
244 }
245
246 }