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 @Override
71 protected final NavigableMap<K, V> getUnderlyingMap()
72 {
73 return (NavigableMap<K, V>) super.getUnderlyingMap();
74 }
75
76 @Override
77 public final NavigableMap<K, V> toMap()
78 {
79 return new TreeMap<K, V>(super.getUnderlyingMap());
80 }
81
82 @Override
83 public final ImmutableSortedSet<K> keySet()
84 {
85 if (this.cachedKeySet == null)
86 {
87 NavigableSet<K> immutableKeySet = new TreeSet<>(getUnderlyingMap().comparator());
88 immutableKeySet.addAll(getUnderlyingMap().keySet());
89 this.cachedKeySet = new ImmutableTreeSet<>(immutableKeySet, Immutable.WRAP);
90 }
91 return this.cachedKeySet;
92 }
93
94 @Override
95 public ImmutableSortedSet<ImmutableEntry<K, V>> entrySet()
96 {
97 if (this.cachedEntrySet == null)
98 {
99 NavigableSet<ImmutableEntry<K, V>> immutableEntrySet = new TreeSet<>(new Comparator<ImmutableEntry<K, V>>()
100 {
101 @SuppressWarnings("unchecked")
102 @Override
103 public int compare(final ImmutableEntry<K, V> o1, final ImmutableEntry<K, V> o2)
104 {
105 return ((Comparable<K>) o1.getKey()).compareTo(o2.getKey());
106 }
107
108 });
109 for (Entry<K, V> entry : getUnderlyingMap().entrySet())
110 {
111 immutableEntrySet.add(new ImmutableEntry<>(entry));
112 }
113 this.cachedEntrySet = new ImmutableTreeSet<>(immutableEntrySet, Immutable.WRAP);
114 }
115 return this.cachedEntrySet;
116 }
117
118 @Override
119 public ImmutableSortedSet<V> values()
120 {
121 if (this.cachedValues == null)
122 {
123 NavigableSet<V> immutableValues = new TreeSet<>(getUnderlyingMap().values());
124 this.cachedValues = new ImmutableTreeSet<>(immutableValues, Immutable.WRAP);
125 }
126 return (ImmutableNavigableSet<V>) this.cachedValues;
127 }
128
129 @Override
130 public final Comparator<? super K> comparator()
131 {
132 return getUnderlyingMap().comparator();
133 }
134
135 @Override
136 public final ImmutableSortedMap<K, V> subMap(final K fromKey, final K toKey)
137 {
138 return new ImmutableTreeMap<K, V>(getUnderlyingMap().subMap(fromKey, toKey));
139 }
140
141 @Override
142 public final ImmutableSortedMap<K, V> headMap(final K toKey)
143 {
144 return new ImmutableTreeMap<K, V>(getUnderlyingMap().headMap(toKey));
145 }
146
147 @Override
148 public final ImmutableSortedMap<K, V> tailMap(final K fromKey)
149 {
150 return new ImmutableTreeMap<K, V>(getUnderlyingMap().tailMap(fromKey));
151 }
152
153 @Override
154 public final K firstKey()
155 {
156 return getUnderlyingMap().firstKey();
157 }
158
159 @Override
160 public final K lastKey()
161 {
162 return getUnderlyingMap().lastKey();
163 }
164
165 @Override
166 public final K lowerKey(final K key)
167 {
168 return getUnderlyingMap().lowerKey(key);
169 }
170
171 @Override
172 public final K floorKey(final K key)
173 {
174 return getUnderlyingMap().floorKey(key);
175 }
176
177 @Override
178 public final K ceilingKey(final K key)
179 {
180 return getUnderlyingMap().ceilingKey(key);
181 }
182
183 @Override
184 public final K higherKey(final K key)
185 {
186 return getUnderlyingMap().higherKey(key);
187 }
188
189 @Override
190 public final ImmutableNavigableMap<K, V> descendingMap()
191 {
192 return new ImmutableTreeMap<K, V>(getUnderlyingMap().descendingMap());
193 }
194
195 @Override
196 public final ImmutableNavigableMap<K, V> subMap(final K fromKey, final boolean fromInclusive, final K toKey,
197 final boolean toInclusive)
198 {
199 return new ImmutableTreeMap<K, V>(getUnderlyingMap().subMap(fromKey, fromInclusive, toKey, toInclusive));
200 }
201
202 @Override
203 public final ImmutableNavigableMap<K, V> headMap(final K toKey, final boolean inclusive)
204 {
205 return new ImmutableTreeMap<K, V>(getUnderlyingMap().headMap(toKey, inclusive));
206 }
207
208 @Override
209 public final ImmutableNavigableMap<K, V> tailMap(final K fromKey, final boolean inclusive)
210 {
211 return new ImmutableTreeMap<K, V>(getUnderlyingMap().tailMap(fromKey, inclusive));
212 }
213
214 @Override
215 public final String toString()
216 {
217 NavigableMap<K, V> map = getUnderlyingMap();
218 if (null == map)
219 {
220 return "ImmutableTreeMap []";
221 }
222 return "ImmutableTreeMap [" + map.toString() + "]";
223 }
224
225 }