Skip to content

Commit 55c4562

Browse files
committed
Add MapBuilder, re #64
1 parent 4a8eed6 commit 55c4562

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed
+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/* Copyright (c) 2024 LibJ
2+
*
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* You should have received a copy of The MIT License (MIT) along with this
14+
* program. If not, see <http://opensource.org/licenses/MIT/>.
15+
*/
16+
17+
package org.libj.util;
18+
19+
import java.util.Map;
20+
21+
/**
22+
* Class providing the builder pattern for the population of key/value pairs into arbitrary {@link Map}s.
23+
*
24+
* @param <K> The type of keys maintained by the map.
25+
* @param <V> The type of mapped values in the map.
26+
* @param <M> The type of the map.
27+
*/
28+
public class MapBuilder<K,V,M extends Map<K,V>> {
29+
/**
30+
* Associates the specified value with the specified key in the target map, and returns the target map.
31+
*
32+
* @param <K> The type of keys maintained by the map.
33+
* @param <V> The type of mapped values in the map.
34+
* @param <M> The type of the map.
35+
* @param map The target {@link Map}.
36+
* @param key Key with which the specified value is to be associated in the target map of this {@link MapBuilder}.
37+
* @param value Value to be associated with the specified key in the target map of this {@link MapBuilder}.
38+
* @return The target {@link Map}.
39+
* @throws UnsupportedOperationException if the {@link Map#put} operation is not supported by the target map of this
40+
* {@link MapBuilder}.
41+
* @throws ClassCastException If the class of the specified key or value prevents it from being stored in the target map of this
42+
* {@link MapBuilder}.
43+
* @throws NullPointerException If the specified key or value is null and the target map of this {@link MapBuilder} does not permit
44+
* null keys or values.
45+
* @throws IllegalArgumentException If some property of the specified key or value prevents it from being stored in the target map
46+
* of this {@link MapBuilder}.
47+
* @throws NullPointerException If the target map of this {@link MapBuilder} is null.
48+
* @see Map#put(Object,Object)
49+
*/
50+
public static <K,V,M extends Map<K,V>> M put(final M map, final K key, final V value) {
51+
map.put(key, value);
52+
return map;
53+
}
54+
55+
/**
56+
* Associates the specified variable array of alternating key and value arguments in the target map, and returns the target map.
57+
*
58+
* @param <K> The type of keys maintained by the map.
59+
* @param <V> The type of mapped values in the map.
60+
* @param <M> The type of the map.
61+
* @param map The target {@link Map}.
62+
* @param keyValue Variable array of alternating key and value arguments.
63+
* @return The target {@link Map}.
64+
* @throws UnsupportedOperationException if the {@link Map#put} operation is not supported by the target map of this
65+
* {@link MapBuilder}.
66+
* @throws ClassCastException If the class of the specified key or value prevents it from being stored in the target map of this
67+
* {@link MapBuilder}.
68+
* @throws NullPointerException If the specified key or value is null and the target map of this {@link MapBuilder} does not permit
69+
* null keys or values.
70+
* @throws IllegalArgumentException If the number of provided key and value arguments is not even, or if some property of the
71+
* specified key or value prevents it from being stored in the target map of this {@link MapBuilder}.
72+
* @throws NullPointerException If the target map of this {@link MapBuilder} is null.
73+
* @see Map#put(Object,Object)
74+
*/
75+
@SuppressWarnings("unchecked")
76+
public static <K,V,M extends Map<K,V>> M put(final M map, final Object ... keyValue) {
77+
final Map m = map;
78+
final int len = keyValue.length;
79+
if (len % 2 != 0)
80+
throw new IllegalArgumentException("Expected an even number of alternating key and value arguments");
81+
82+
for (int i = 0; i < len; m.put(keyValue[i++], keyValue[i++])); // [A]
83+
return map;
84+
}
85+
86+
private final M map;
87+
88+
/**
89+
* Creates a new {@link MapBuilder} with the provided {@link Map} as the target map of the builder pattern.
90+
*
91+
* @param map The target {@link Map} of the builder pattern.
92+
*/
93+
public MapBuilder(final M map) {
94+
this.map = map;
95+
}
96+
97+
/**
98+
* Associates the specified value with the specified key in the target map of this {@link MapBuilder}, and returns {@code this}
99+
* {@link MapBuilder}.
100+
*
101+
* @param key Key with which the specified value is to be associated in the target map of this {@link MapBuilder}.
102+
* @param value Value to be associated with the specified key in the target map of this {@link MapBuilder}.
103+
* @return {@code this} {@link MapBuilder}.
104+
* @throws UnsupportedOperationException if the {@link Map#put} operation is not supported by the target map of this
105+
* {@link MapBuilder}.
106+
* @throws ClassCastException If the class of the specified key or value prevents it from being stored in the target map of this
107+
* {@link MapBuilder}.
108+
* @throws NullPointerException If the specified key or value is null and the target map of this {@link MapBuilder} does not permit
109+
* null keys or values.
110+
* @throws IllegalArgumentException If some property of the specified key or value prevents it from being stored in the target map
111+
* of this {@link MapBuilder}.
112+
* @throws NullPointerException If the target map of this {@link MapBuilder} is null.
113+
* @see Map#put(Object,Object)
114+
*/
115+
public MapBuilder<K,V,M> put(final K key, final V value) {
116+
map.put(key, value);
117+
return this;
118+
}
119+
120+
/**
121+
* Copies all of the mappings from the specified map to the target map of this {@link MapBuilder}, and returns {@code this}
122+
* {@link MapBuilder}. The effect of this call is equivalent to that of calling {@link #put(Object,Object) put(k, v)} on this
123+
* {@link MapBuilder} once for each mapping from key {@code k} to value {@code v} in the specified map. The behavior of this
124+
* operation is undefined if the specified map is modified while the operation is in progress.
125+
*
126+
* @return {@code this} {@link MapBuilder}.
127+
* @param m Mappings to be stored in the target map of this {@link MapBuilder}.
128+
* @throws UnsupportedOperationException If the {@link Map#putAll} operation is not supported by the target map of this
129+
* {@link MapBuilder}.
130+
* @throws ClassCastException If the class of a key or value in the specified map prevents it from being stored in the target map of
131+
* this {@link MapBuilder}.
132+
* @throws NullPointerException If the specified map is null, or if the target map of this {@link MapBuilder} does not permit null
133+
* keys or values, and the specified map contains null keys or values.
134+
* @throws IllegalArgumentException If some property of a key or value in the specified map prevents it from being stored in the
135+
* target map of this {@link MapBuilder}.
136+
* @throws NullPointerException If the target map of this {@link MapBuilder} is null.
137+
* @see Map#putAll(Map)
138+
*/
139+
public MapBuilder<K,V,M> putAll(final Map<? extends K,? extends V> m) {
140+
map.putAll(m);
141+
return this;
142+
}
143+
144+
/**
145+
* If the specified key is not already associated with a value in the target map of this {@link MapBuilder} (or is mapped to
146+
* {@code null}), this method associates the specified key with the given value, and returns {@code this} {@link MapBuilder}.
147+
*
148+
* @param key Key with which the specified value is to be associated in the target map of this {@link MapBuilder}.
149+
* @param value Value to be associated with the specified key in the target map of this {@link MapBuilder}.
150+
* @return {@code this} {@link MapBuilder}.
151+
* @throws UnsupportedOperationException If the {@link Map#put} operation is not supported by the target map of this
152+
* {@link MapBuilder}.
153+
* @throws ClassCastException If the key or value is of an inappropriate type for the target map of this {@link MapBuilder}.
154+
* @throws NullPointerException If the specified key or value is null, and the target map of this {@link MapBuilder} does not permit
155+
* null keys or values.
156+
* @throws IllegalArgumentException If some property of the specified key or value prevents it from being stored in the target map
157+
* of this {@link MapBuilder}.
158+
* @throws NullPointerException If the target map of this {@link MapBuilder} is null.
159+
* @see Map#putIfAbsent(Object,Object)
160+
*/
161+
public MapBuilder<K,V,M> putIfAbsent(final K key, final V value) {
162+
map.putIfAbsent(key, value);
163+
return this;
164+
}
165+
166+
public M build() {
167+
return map;
168+
}
169+
}

0 commit comments

Comments
 (0)