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