-
Notifications
You must be signed in to change notification settings - Fork 1
/
TypedMap.java
265 lines (224 loc) · 7.67 KB
/
TypedMap.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
package dev.voidframework.core.lang;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Typed key-value map.
*
* @since 1.0.0
*/
public final class TypedMap {
private final Map<Key<?>, Object> internalMap;
/**
* Build a new instance.
*
* @since 1.0.0
*/
public TypedMap() {
this.internalMap = new HashMap<>();
}
/**
* Returns a typed map.
*
* @param key The mapping key
* @param value The mapping value
* @param <K> The type of the Key object
* @param <V> The type of the Value object
* @return A typed map containing the specified mapping
*/
public static <K, V extends K> TypedMap of(final Key<K> key, final V value) {
final TypedMap typedMap = new TypedMap();
typedMap.put(key, value);
return typedMap;
}
/**
* Returns a typed map.
*
* @param key1 The first mapping key
* @param value1 The first mapping value
* @param key2 The second mapping key
* @param value2 The second mapping value
* @param <K1> The type of the first Key object
* @param <V1> The type of the first Value object
* @param <K2> The type of the second Key object
* @param <V2> The type of the second Value object
* @return A typed map containing the specified mapping
*/
public static <K1, V1 extends K1, K2, V2 extends K2>
TypedMap of(final Key<K1> key1,
final V1 value1,
final Key<K2> key2,
final V2 value2) {
final TypedMap typedMap = new TypedMap();
typedMap.put(key1, value1);
typedMap.put(key2, value2);
return typedMap;
}
/**
* Returns a typed map.
*
* @param key1 The first mapping key
* @param value1 The first mapping value
* @param key2 The second mapping key
* @param value2 The second mapping value
* @param key3 The third mapping key
* @param value3 The third mapping value
* @param <K1> The type of the first Key object
* @param <V1> The type of the first Value object
* @param <K2> The type of the second Key object
* @param <V2> The type of the second Value object
* @param <K3> The type of the third Key object
* @param <V3> The type of the third Value object
* @return A typed map containing the specified mapping
*/
public static <K1, V1 extends K1, K2, V2 extends K2, K3, V3 extends K3>
TypedMap of(final Key<K1> key1,
final V1 value1,
final Key<K2> key2,
final V2 value2,
final Key<K3> key3,
final V3 value3) {
final TypedMap typedMap = new TypedMap();
typedMap.put(key1, value1);
typedMap.put(key2, value2);
typedMap.put(key3, value3);
return typedMap;
}
/**
* Returns a typed map.
*
* @param key1 The first mapping key
* @param value1 The first mapping value
* @param key2 The second mapping key
* @param value2 The second mapping value
* @param key3 The third mapping key
* @param value3 The third mapping value
* @param key4 The fourth mapping key
* @param value4 The fourth mapping value
* @param <K1> The type of the first Key object
* @param <V1> The type of the first Value object
* @param <K2> The type of the second Key object
* @param <V2> The type of the second Value object
* @param <K3> The type of the third Key object
* @param <V3> The type of the third Value object
* @param <K4> The type of the fourth Key object
* @param <V4> The type of the fourth Value object
* @return A typed map containing the specified mapping
*/
public static <K1, V1 extends K1, K2, V2 extends K2, K3, V3 extends K3, K4, V4 extends K4>
TypedMap of(final Key<K1> key1, // NOSONAR "Method has 8 parameters, which is greater than n"
final V1 value1,
final Key<K2> key2,
final V2 value2,
final Key<K3> key3,
final V3 value3,
final Key<K4> key4,
final V4 value4) {
final TypedMap typedMap = new TypedMap();
typedMap.put(key1, value1);
typedMap.put(key2, value2);
typedMap.put(key3, value3);
typedMap.put(key4, value4);
return typedMap;
}
/**
* Retrieves the value associated to the specified key.
*
* @param typedKey The typed key
* @param <T> The value type
* @return The value associated to the specified key, otherwise, {@code null}
* @since 1.0.0
*/
@SuppressWarnings("unchecked")
public <T> T get(final Key<T> typedKey) {
return (T) this.internalMap.get(typedKey);
}
/**
* Associates the specified value with the specified key.
*
* @param typedKey The typed key
* @param value The value to associate with the given key
* @param <T> The value type
* @return The previous value associated with key, otherwise, {@code null}
* @since 1.0.0
*/
@SuppressWarnings("unchecked")
public <T> T put(final Key<T> typedKey, T value) {
return (T) this.internalMap.put(typedKey, value);
}
/**
* Removes the value associated to the specified key.
*
* @param typedKey The typed key
* @param <T> The value type
* @return The value associated to the specified key, otherwise, {@code null}
* @since 1.0.0
*/
@SuppressWarnings("unchecked")
public <T> T remove(final Key<T> typedKey) {
return (T) this.internalMap.remove(typedKey);
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final TypedMap typedMap = (TypedMap) o;
return internalMap.equals(typedMap.internalMap);
}
@Override
public int hashCode() {
return Objects.hash(internalMap);
}
@Override
public String toString() {
return this.internalMap.toString();
}
/**
* TypedMap Key.
*
* @param <T> Type of value associated to the key
* @since 1.0.0
*/
public static final class Key<T> {
private final String keyName;
private final Class<T> valueClassType;
/**
* Build a new instance.
*
* @param keyName The key name
* @param valueClassType The value class type
* @since 1.0.0
*/
private Key(final String keyName, final Class<T> valueClassType) {
this.keyName = keyName;
this.valueClassType = valueClassType;
}
/**
* Build a new key.
*
* @param keyName The key name
* @param valueClassType The value class type
* @param <V> Type of value associated to the key
* @return The created key
* @since 1.0.0
*/
public static <V> Key<V> of(final String keyName, final Class<V> valueClassType) {
return new Key<>(keyName, valueClassType);
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Key<?> key = (Key<?>) o;
return keyName.equals(key.keyName) && valueClassType.equals(key.valueClassType);
}
@Override
public int hashCode() {
return Objects.hash(keyName, valueClassType);
}
@Override
public String toString() {
return this.keyName;
}
}
}