All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.iti.wakamiti.api.util.MapUtils Maven / Gradle / Ivy

The newest version!
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
package es.iti.wakamiti.api.util;


import java.util.AbstractMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collector;


@SuppressWarnings({"java:S107"})
public class MapUtils {

    private MapUtils() {

    }

    /**
     * Returns a linked map containing zero mappings.
     * See Unmodifiable Maps for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @return an empty {@code Map}
     */
    public static  Map map() {
        return new MapN<>();
    }

    /**
     * Returns a linked map containing one mapping.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k, V v) {
        return new MapN<>(k, v);
    }

    /**
     * Returns a linked map containing two mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2) {
        return new MapN<>(k1, v1, k2, v2);
    }

    /**
     * Returns a linked map containing three mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3) {
        return new MapN<>(k1, v1, k2, v2, k3, v3);
    }

    /**
     * Returns a linked map containing four mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
        return new MapN<>(k1, v1, k2, v2, k3, v3, k4, v4);
    }

    /**
     * Returns a linked map containing five mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
        return new MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5);
    }

    /**
     * Returns a linked map containing six mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @param k6 the sixth mapping's key
     * @param v6 the sixth mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                                          K k6, V v6) {
        return new MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6);
    }

    /**
     * Returns a linked map containing seven mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @param k6 the sixth mapping's key
     * @param v6 the sixth mapping's value
     * @param k7 the seventh mapping's key
     * @param v7 the seventh mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                                          K k6, V v6, K k7, V v7) {
        return new MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7);
    }

    /**
     * Returns a linked map containing eight mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @param k6 the sixth mapping's key
     * @param v6 the sixth mapping's value
     * @param k7 the seventh mapping's key
     * @param v7 the seventh mapping's value
     * @param k8 the eighth mapping's key
     * @param v8 the eighth mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                                          K k6, V v6, K k7, V v7, K k8, V v8) {
        return new MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8);
    }

    /**
     * Returns a linked map containing nine mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @param k6 the sixth mapping's key
     * @param v6 the sixth mapping's value
     * @param k7 the seventh mapping's key
     * @param v7 the seventh mapping's value
     * @param k8 the eighth mapping's key
     * @param v8 the eighth mapping's value
     * @param k9 the ninth mapping's key
     * @param v9 the ninth mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                                          K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
        return new MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9);
    }

    /**
     * Returns a linked map containing ten mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @param k6 the sixth mapping's key
     * @param v6 the sixth mapping's value
     * @param k7 the seventh mapping's key
     * @param v7 the seventh mapping's value
     * @param k8 the eighth mapping's key
     * @param v8 the eighth mapping's value
     * @param k9 the ninth mapping's key
     * @param v9 the ninth mapping's value
     * @param k10 the tenth mapping's key
     * @param v10 the tenth mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                                          K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
        return new MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10);
    }

    /**
     * Returns a linked map containing eleven mappings.
     * See {@link LinkedHashMap} for details.
     *
     * @param  the {@code Map}'s key type
     * @param  the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @param k6 the sixth mapping's key
     * @param v6 the sixth mapping's value
     * @param k7 the seventh mapping's key
     * @param v7 the seventh mapping's value
     * @param k8 the eighth mapping's key
     * @param v8 the eighth mapping's value
     * @param k9 the ninth mapping's key
     * @param v9 the ninth mapping's value
     * @param k10 the tenth mapping's key
     * @param v10 the tenth mapping's value
     * @param k11 the eleventh mapping's key
     * @param v11 the eleventh mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     */
    public static  Map map(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                                          K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10,
                                          K k11, V v11) {
        return new MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11);
    }

    /**
     * Returns a linked map containing keys and values extracted from the given entries.
     * The entries themselves are not stored in the map.
     * See {@link LinkedHashMap} for details.
     *
     * @apiNote
     * It is convenient to create the map entries using the {@link #entry} method.
     * For example,
     *
     * 
{@code
     *     import static java.util.Map.entry;
     *
     *     Map map = MapUtils.mapEntries(
     *         entry(1, "a"),
     *         entry(2, "b"),
     *         entry(3, "c"),
     *         ...
     *         entry(26, "z"));
     * }
* * @param the {@code Map}'s key type * @param the {@code Map}'s value type * @param entries {@code Map.Entry}s containing the keys and values from which the map is populated * @return a {@code Map} containing the specified mappings * @throws IllegalArgumentException if there are any duplicate keys * @throws NullPointerException if any entry, key, or value is {@code null}, or if * the {@code entries} array is {@code null} * * @see #entry */ @SafeVarargs @SuppressWarnings("varargs") public static Map mapEntries(Map.Entry... entries) { if (entries.length == 0) { // implicit null check of entries array @SuppressWarnings("unchecked") var map = (LinkedHashMap) map(); return map; } else if (entries.length == 1) { // implicit null check of the array slot return map(entries[0].getKey(), entries[0].getValue()); } else { Object[] kva = new Object[entries.length << 1]; int a = 0; for (Map.Entry entry : entries) { // implicit null checks of each array slot kva[a++] = entry.getKey(); kva[a++] = entry.getValue(); } return new MapN<>(kva); } } /** * Returns a {@link Map.Entry} containing the given key and value. * These entries are suitable for populating {@code Map} instances using the * {@link #mapEntries MapUtils.mapEntries()} method. * The {@code Entry} instances created by this method have the following characteristics: * *
    *
  • They disallow {@code null} keys and values. Attempts to create them using a {@code null} * key or value result in {@code NullPointerException}. *
  • They are unmodifiable. Calls to {@link Map.Entry#setValue Entry.setValue()} * on a returned {@code Entry} result in {@code UnsupportedOperationException}. *
  • They are not serializable. *
  • They are value-based. * Programmers should treat instances that are {@linkplain #equals(Object) equal} * as interchangeable and should not use them for synchronization, or * unpredictable behavior may occur. For example, in a future release, * synchronization may fail. Callers should make no assumptions * about the identity of the returned instances. This method is free to * create new instances or reuse existing ones. *
* * @apiNote * For a serializable {@code Entry}, see {@link AbstractMap.SimpleEntry}. * * @param the key's type * @param the value's type * @param k the key * @param v the value * @return an {@code Entry} containing the specified key and value * @throws NullPointerException if the key or value is {@code null} * * @see #mapEntries MapUtils.mapEntries() */ public static Map.Entry entry(K k, V v) { return new AbstractMap.SimpleEntry<>(k, v); } /** * An array-based Map implementation. * It must also be strictly larger than the size (the number of key-value pairs contained * in the map) so that at least one null key is always present. * @param the key type * @param the value type */ static final class MapN extends LinkedHashMap { MapN (Object... input) { if ((input.length & 1) != 0) { // implicit nullcheck of input throw new InternalError("length is odd"); } for (int i = 0; i < input.length; i += 2) { @SuppressWarnings("unchecked") K k = Objects.requireNonNull((K) input[i]); @SuppressWarnings("unchecked") V v = (V) input[i + 1]; if (containsKey(k)) { throw new IllegalArgumentException("duplicate key: " + k); } else { put(k, v); } } } } /** * Collects elements into a map using the specified key and value mappers. * * @param keyMapper A function to extract keys from elements * @param valueMapper A function to extract values from elements * @param The type of elements to collect * @param The type of keys * @param The type of values * @return A collector that accumulates elements into a map */ public static , K, U> Collector> entryCollector( Function keyMapper, Function valueMapper ) { return Collector.of( LinkedHashMap::new, (m, e) -> m.put(keyMapper.apply(e), valueMapper.apply(e)), (m, r) -> m ); } public static Collector, ?, Map> toMap( Function keyMapper, Function valueMapper ) { return Collector.of( LinkedHashMap::new, (m, e) -> m.put(keyMapper.apply(e.getKey()), valueMapper.apply(e.getValue())), (m, r) -> m ); } public static Collector, ?, Map> toMap( Function valueMapper ) { return toMap(Function.identity(), valueMapper); } public static Collector, ?, Map> toMap() { return toMap(Function.identity()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy