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