001// Generated by delombok at Sat Feb 25 17:58:34 UTC 2023
002package io.cui.tools.collect;
003
004import static io.cui.tools.collect.CollectionLiterals.mutableMap;
005import static java.util.Objects.requireNonNull;
006import java.util.Collections;
007import java.util.HashMap;
008import java.util.Map;
009import java.util.Map.Entry;
010
011/**
012 * <h2>Overview</h2>
013 * <p>
014 * Builder for creating {@link java.util.Map}s providing some convenience methods. The class writes
015 * everything through into the contained collector. Using the default constructor a newly created
016 * {@link java.util.HashMap} will be used as collector, but you can pass you own collector as
017 * constructor-argument. Of course this should be mutable in order to work.
018 * </p>
019 * <p>
020 * Although not being a {@link java.util.Map} itself it provides the same methods with different
021 * semantics -&gt; Builder approach.
022 * </p>
023 * <h3>Standard Usage</h3>
024 *
025 * <pre>
026 * MapBuilder&lt;String, String&gt; builder = new MapBuilder&lt;&gt;();
027 * builder.put("key1", "value1").put("key2", "value2");
028 * assertEquals(2, builder.size());
029 * assertMutable(builder.toMutableMap());
030 * assertImmutable(builder.toImmutableMap());
031 * </pre>
032 *
033 * <h3>Using from()</h3>
034 * This methods can be used for ensuring a real copy
035 *
036 * <pre>
037 * assertEquals(4, MapBuilder.from("key1", 1, "key2", 2, "key3", 3, "key4", 4).size());
038 * </pre>
039 *
040 * @author Oliver Wolff
041 * @param <K> the type of keys maintained by this map
042 * @param <V> the type of mapped values
043 */
044public final class MapBuilder<K, V> {
045    private final Map<K, V> collector;
046
047    /**
048     * Default Constructor initializing the collector with an {@link java.util.HashMap}
049     */
050    public MapBuilder() {
051        this(new HashMap<>());
052    }
053
054    /**
055     * <p>
056     * Constructor for MapBuilder.
057     * </p>
058     *
059     * @param collector to be used for storage. Must not be null
060     */
061    public MapBuilder(Map<K, V> collector) {
062        this.collector = requireNonNull(collector);
063    }
064
065    /**
066     * <p>
067     * size.
068     * </p>
069     *
070     * @return the number of key-value mappings in this map
071     * @see Map#size()
072     */
073    public int size() {
074        return collector.size();
075    }
076
077    /**
078     * <p>
079     * isEmpty.
080     * </p>
081     *
082     * @return true if this map contains no key-value mappings
083     * @see Map#isEmpty()
084     */
085    public boolean isEmpty() {
086        return collector.isEmpty();
087    }
088
089    /**
090     * Returns {@code true} if this map contains a mapping for the specified
091     * key. More formally, returns {@code true} if and only if
092     * this map contains a mapping for a key {@code k} such that
093     * {@code (key==null ? k==null : key.equals(k))}. (There can be
094     * at most one such mapping.)
095     *
096     * @param key key whose presence in this map is to be tested
097     * @return {@code true} if this map contains a mapping for the specified
098     *         key
099     * @see Map#containsKey(Object)
100     */
101    public boolean containsKey(Object key) {
102        return collector.containsKey(key);
103    }
104
105    /**
106     * Returns {@code true} if this map maps one or more keys to the
107     * specified value. More formally, returns {@code true} if and only if
108     * this map contains at least one mapping to a value {@code v} such that
109     * {@code (value==null ? v==null : value.equals(v))}. This operation
110     * will probably require time linear in the map size for most
111     * implementations of the {@code Map} interface.
112     *
113     * @param value value whose presence in this map is to be tested
114     * @return {@code true} if this map maps one or more keys to the
115     *         specified value
116     * @see Map#containsValue(Object)
117     */
118    public boolean containsValue(Object value) {
119        return collector.containsValue(value);
120    }
121
122    /**
123     * <p>
124     * put.
125     * </p>
126     *
127     * @param key to be put as key, must not be empty
128     * @param value to be put as value, must not be empty
129     * @return the instance itself in order to use it in a fluent way.
130     */
131    public MapBuilder<K, V> put(K key, V value) {
132        collector.put(key, value);
133        return this;
134    }
135
136    /**
137     * Puts the entry into the map, if the value is not {@code null}.
138     *
139     * @param key to be put as key, must not be empty
140     * @param value to be put as value
141     * @return the instance itself in order to use it in a fluent way.
142     */
143    public MapBuilder<K, V> putIfNotNull(K key, V value) {
144        if (null != value) {
145            collector.put(key, value);
146        }
147        return this;
148    }
149
150    /**
151     * <p>
152     * put.
153     * </p>
154     *
155     * @param entry to be put, must not {@code null}
156     * @return the instance itself in order to use it in a fluent way.
157     */
158    public MapBuilder<K, V> put(Entry<? extends K, ? extends V> entry) {
159        collector.put(entry.getKey(), entry.getValue());
160        return this;
161    }
162
163    /**
164     * <p>
165     * remove.
166     * </p>
167     *
168     * @param key to be removed
169     * @return the instance itself in order to use it in a fluent way.
170     */
171    public MapBuilder<K, V> remove(Object key) {
172        collector.remove(key);
173        return this;
174    }
175
176    /**
177     * <p>
178     * putAll.
179     * </p>
180     *
181     * @param map to be put
182     * @return the instance itself in order to use it in a fluent way.
183     */
184    public MapBuilder<K, V> putAll(Map<? extends K, ? extends V> map) {
185        collector.putAll(map);
186        return this;
187    }
188
189    /**
190     * Clears the contained collector
191     *
192     * @return the instance itself in order to use it in a fluent way.
193     */
194    public MapBuilder<K, V> clear() {
195        collector.clear();
196        return this;
197    }
198
199    /**
200     * <p>
201     * toMutableMap.
202     * </p>
203     *
204     * @return a mutable {@link java.util.Map} representation of the builders content, the actual
205     *         implementation is a {@link java.util.HashMap}
206     */
207    public Map<K, V> toMutableMap() {
208        return new HashMap<>(collector);
209    }
210
211    /**
212     * <p>
213     * toImmutableMap.
214     * </p>
215     *
216     * @return an immutable {@link java.util.Map} representation of the builders content, the actual
217     *         implementation does not create a copy but provides an unmodifiable view using
218     *         {@link java.util.Collections#unmodifiableMap(Map)}
219     */
220    public Map<K, V> toImmutableMap() {
221        return Collections.unmodifiableMap(collector);
222    }
223
224    /**
225     * <p>
226     * copyFrom.
227     * </p>
228     *
229     * @param <K> the type of keys maintained by this map
230     * @param <V> the type of mapped values
231     * @param original map used to initialize the contained collector
232     * @return an instance of {@link io.cui.tools.collect.MapBuilder} initialized with a copy of the
233     *         given Map.
234     */
235    public static <K, V> MapBuilder<K, V> copyFrom(Map<K, V> original) {
236        return new MapBuilder<>(new HashMap<>(original));
237    }
238
239    /**
240     * Shorthand for creating a {@link io.cui.tools.collect.MapBuilder} from a given key/value pair
241     *
242     * @param <K> the type of keys maintained by this map
243     * @param <V> the type of mapped values
244     * @param k1 key to be added
245     * @param v1 value to be added
246     * @return an instance of {@link io.cui.tools.collect.MapBuilder} initialized with the given
247     *         key/value pair.
248     */
249    public static <K, V> MapBuilder<K, V> from(K k1, V v1) {
250        return new MapBuilder<>(mutableMap(k1, v1));
251    }
252
253    /**
254     * Shorthand for creating a {@link io.cui.tools.collect.MapBuilder} from given key/value pairs
255     *
256     * @param <K> the type of keys maintained by this map
257     * @param <V> the type of mapped values
258     * @param k1 key to be added
259     * @param v1 value to be added
260     * @param k2 key to be added
261     * @param v2 value to be added
262     * @return an instance of {@link io.cui.tools.collect.MapBuilder} initialized with the given
263     *         key/value pairs.
264     */
265    public static <K, V> MapBuilder<K, V> from(K k1, V v1, K k2, V v2) {
266        return new MapBuilder<>(mutableMap(k1, v1, k2, v2));
267    }
268
269    /**
270     * Shorthand for creating a {@link io.cui.tools.collect.MapBuilder} from given key/value pairs
271     *
272     * @param <K> the type of keys maintained by this map
273     * @param <V> the type of mapped values
274     * @param k1 key to be added
275     * @param v1 value to be added
276     * @param k2 key to be added
277     * @param v2 value to be added
278     * @param k3 key to be added
279     * @param v3 value to be added
280     * @return an instance of {@link io.cui.tools.collect.MapBuilder} initialized with the given
281     *         key/value pairs.
282     */
283    public static <K, V> MapBuilder<K, V> from(K k1, V v1, K k2, V v2, K k3, V v3) {
284        return new MapBuilder<>(mutableMap(k1, v1, k2, v2, k3, v3));
285    }
286
287    // owolff: Number of parameters match to the use-case
288    /**
289     * Shorthand for creating a {@link io.cui.tools.collect.MapBuilder} from given key/value pairs
290     *
291     * @param <K> the type of keys maintained by this map
292     * @param <V> the type of mapped values
293     * @param k1 key to be added
294     * @param v1 value to be added
295     * @param k2 key to be added
296     * @param v2 value to be added
297     * @param k3 key to be added
298     * @param v3 value to be added
299     * @param k4 key to be added
300     * @param v4 value to be added
301     * @return an instance of {@link io.cui.tools.collect.MapBuilder} initialized with the given
302     *         key/value pairs.
303     */
304    @SuppressWarnings("squid:S00107")
305    public static <K, V> MapBuilder<K, V> from(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
306        return new MapBuilder<>(mutableMap(k1, v1, k2, v2, k3, v3, k4, v4));
307    }
308
309    @java.lang.Override
310    @java.lang.SuppressWarnings("all")
311    @lombok.Generated
312    public boolean equals(final java.lang.Object o) {
313        if (o == this) return true;
314        if (!(o instanceof MapBuilder)) return false;
315        final MapBuilder<?, ?> other = (MapBuilder<?, ?>) o;
316        final java.lang.Object this$collector = this.collector;
317        final java.lang.Object other$collector = other.collector;
318        if (this$collector == null ? other$collector != null : !this$collector.equals(other$collector)) return false;
319        return true;
320    }
321
322    @java.lang.Override
323    @java.lang.SuppressWarnings("all")
324    @lombok.Generated
325    public int hashCode() {
326        final int PRIME = 59;
327        int result = 1;
328        final java.lang.Object $collector = this.collector;
329        result = result * PRIME + ($collector == null ? 43 : $collector.hashCode());
330        return result;
331    }
332
333    @java.lang.Override
334    @java.lang.SuppressWarnings("all")
335    @lombok.Generated
336    public java.lang.String toString() {
337        return "MapBuilder(collector=" + this.collector + ")";
338    }
339}