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

io.vavr.collection.LinkedHashMultimap Maven / Gradle / Ivy

There is a newer version: 1.0.0-alpha-4
Show newest version
/*  __    __  __  __    __  ___
 * \  \  /  /    \  \  /  /  __/
 *  \  \/  /  /\  \  \/  /  /
 *   \____/__/  \__\____/__/
 *
 * Copyright 2014-2019 Vavr, http://vavr.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.vavr.collection;

import io.vavr.Tuple2;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

/**
 * A {@link LinkedHashMap}-based implementation of {@link Multimap}
 *
 * @param  Key type
 * @param  Value type
 * @author Ruslan Sennov
 */
public final class LinkedHashMultimap extends AbstractMultimap> implements Serializable {

    private static final long serialVersionUID = 1L;

    public static  Builder withSeq() {
        return new Builder<>(ContainerType.SEQ, List::empty);
    }

    public static  Builder withSet() {
        return new Builder<>(ContainerType.SET, HashSet::empty);
    }

    public static > Builder withSortedSet() {
        return new Builder<>(ContainerType.SORTED_SET, TreeSet::empty);
    }

    public static  Builder withSortedSet(Comparator comparator) {
        return new Builder<>(ContainerType.SORTED_SET, () -> TreeSet.empty(comparator));
    }

    public static class Builder {

        private final ContainerType containerType;
        private final SerializableSupplier> emptyContainer;

        private Builder(ContainerType containerType, SerializableSupplier> emptyContainer) {
            this.containerType = containerType;
            this.emptyContainer = emptyContainer;
        }

        /**
         * Returns the empty {@code LinkedHashMultimap}.
         *
         * @param  The key type
         * @param  The value type
         * @return A new empty LinkedHashMultimap.
         */
        public  LinkedHashMultimap empty() {
            return new LinkedHashMultimap<>(LinkedHashMap.empty(), containerType, emptyContainer);
        }

        /**
         * Creates a {@code LinkedHashMultimap} of the given entries.
         *
         * @param            The key type
         * @param           The value type
         * @param entries       Multimap entries
         * @return A new LinkedHashMultimap containing the given entries.
         */
        public  LinkedHashMultimap ofEntries(Iterable> entries) {
            Objects.requireNonNull(entries, "entries is null");
            LinkedHashMultimap result = empty();
            for (Tuple2 entry : entries) {
                result = result.put(entry._1, entry._2);
            }
            return result;
        }

        /**
         * Creates a {@code LinkedHashMultimap} of the given entries.
         *
         * @param            The key type
         * @param           The value type
         * @param entries       Multimap entries
         * @return A new LinkedHashMultimap containing the given entries.
         */
        @SafeVarargs
        public final  LinkedHashMultimap ofEntries(Tuple2... entries) {
            Objects.requireNonNull(entries, "entries is null");
            LinkedHashMultimap result = empty();
            for (Tuple2 entry : entries) {
                result = result.put(entry._1, entry._2);
            }
            return result;
        }

        /**
         * Creates a {@code LinkedHashMultimap} of the given entries.
         *
         * @param            The key type
         * @param           The value type
         * @param entries       Multimap entries
         * @return A new LinkedHashMultimap containing the given entries.
         */
        @SafeVarargs
        public final  LinkedHashMultimap ofEntries(java.util.Map.Entry... entries) {
            Objects.requireNonNull(entries, "entries is null");
            LinkedHashMultimap result = empty();
            for (java.util.Map.Entry entry : entries) {
                result = result.put(entry.getKey(), entry.getValue());
            }
            return result;
        }

        /**
         * Returns a {@code LinkedHashMultimap}, from a source java.util.Map.
         *
         * @param map A map
         * @param  The key type
         * @param  The value type
         * @return A new Multimap containing the given map entries
         */
        public  LinkedHashMultimap ofAll(java.util.Map map) {
            return Multimaps.ofJavaMap(empty(), map);
        }

        /**
         * Returns a {@code LinkedHashMultimap}, from entries mapped from stream.
         *
         * @param stream      the source stream
         * @param keyMapper   the key mapper
         * @param valueMapper the value mapper
         * @param          The stream element type
         * @param          The key type
         * @param         The value type
         * @return A new Multimap
         */
        public  LinkedHashMultimap ofAll(java.util.stream.Stream stream,
                                                              Function keyMapper,
                                                              Function valueMapper) {
            return Multimaps.ofStream(empty(), stream, keyMapper, valueMapper);
        }

        /**
         * Returns a {@code LinkedHashMultimap}, from entries mapped from stream.
         *
         * @param stream      the source stream
         * @param entryMapper the entry mapper
         * @param          The stream element type
         * @param          The key type
         * @param         The value type
         * @return A new Multimap
         */
        public  LinkedHashMultimap ofAll(java.util.stream.Stream stream,
                                                             Function> entryMapper) {
            return Multimaps.ofStream(empty(), stream, entryMapper);
        }

        /**
         * Returns a LinkedHashMultimap containing {@code n} values of a given Function {@code f}
         * over a range of integer values from 0 to {@code n - 1}.
         *
         * @param  The key type
         * @param  The value type
         * @param n   The number of elements in the LinkedHashMultimap
         * @param f   The Function computing element values
         * @return A LinkedHashMultimap consisting of elements {@code f(0),f(1), ..., f(n - 1)}
         * @throws NullPointerException if {@code f} is null
         */
        @SuppressWarnings("unchecked")
        public  LinkedHashMultimap tabulate(int n, Function> f) {
            Objects.requireNonNull(f, "f is null");
            return ofEntries(Collections.tabulate(n, (Function>) f));
        }

        /**
         * Returns a LinkedHashMultimap containing {@code n} values supplied by a given Supplier {@code s}.
         *
         * @param  The key type
         * @param  The value type
         * @param n   The number of elements in the LinkedHashMultimap
         * @param s   The Supplier computing element values
         * @return A LinkedHashMultimap of size {@code n}, where each element contains the result supplied by {@code s}.
         * @throws NullPointerException if {@code s} is null
         */
        @SuppressWarnings("unchecked")
        public  LinkedHashMultimap fill(int n, Supplier> s) {
            Objects.requireNonNull(s, "s is null");
            return ofEntries(Collections.fill(n, (Supplier>) s));
        }

        /**
         * Returns a LinkedHashMultimap containing {@code n} times the given {@code element}
         *
         * @param      The key type
         * @param     The value type
         * @param n       The number of elements in the LinkedHashMultimap
         * @param element The element
         * @return A LinkedHashMultimap of size {@code 1}, where each element contains {@code n} values of {@code element._2}.
         */
        @SuppressWarnings("unchecked")
        public  LinkedHashMultimap fill(int n, Tuple2 element) {
            return ofEntries(Collections.fillObject(n, element));
        }

        /**
         * Creates a LinkedHashMultimap of the given key-value pair.
         *
         * @param key   A singleton map key.
         * @param value A singleton map value.
         * @param    The key type
         * @param   The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K key, V2 value) {
            final LinkedHashMultimap e = empty();
            return e.put(key, value);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2) {
            return of(k1, v1).put(k2, v2);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param k3   a key for the map
         * @param v3   the value for k3
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2, K k3, V2 v3) {
            return of(k1, v1, k2, v2).put(k3, v3);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param k3   a key for the map
         * @param v3   the value for k3
         * @param k4   a key for the map
         * @param v4   the value for k4
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2, K k3, V2 v3, K k4, V2 v4) {
            return of(k1, v1, k2, v2, k3, v3).put(k4, v4);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param k3   a key for the map
         * @param v3   the value for k3
         * @param k4   a key for the map
         * @param v4   the value for k4
         * @param k5   a key for the map
         * @param v5   the value for k5
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2, K k3, V2 v3, K k4, V2 v4, K k5, V2 v5) {
            return of(k1, v1, k2, v2, k3, v3, k4, v4).put(k5, v5);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param k3   a key for the map
         * @param v3   the value for k3
         * @param k4   a key for the map
         * @param v4   the value for k4
         * @param k5   a key for the map
         * @param v5   the value for k5
         * @param k6   a key for the map
         * @param v6   the value for k6
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2, K k3, V2 v3, K k4, V2 v4, K k5, V2 v5, K k6, V2 v6) {
            return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5).put(k6, v6);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param k3   a key for the map
         * @param v3   the value for k3
         * @param k4   a key for the map
         * @param v4   the value for k4
         * @param k5   a key for the map
         * @param v5   the value for k5
         * @param k6   a key for the map
         * @param v6   the value for k6
         * @param k7   a key for the map
         * @param v7   the value for k7
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2, K k3, V2 v3, K k4, V2 v4, K k5, V2 v5, K k6, V2 v6, K k7, V2 v7) {
            return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6).put(k7, v7);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param k3   a key for the map
         * @param v3   the value for k3
         * @param k4   a key for the map
         * @param v4   the value for k4
         * @param k5   a key for the map
         * @param v5   the value for k5
         * @param k6   a key for the map
         * @param v6   the value for k6
         * @param k7   a key for the map
         * @param v7   the value for k7
         * @param k8   a key for the map
         * @param v8   the value for k8
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2, K k3, V2 v3, K k4, V2 v4, K k5, V2 v5, K k6, V2 v6, K k7, V2 v7, K k8, V2 v8) {
            return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7).put(k8, v8);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param k3   a key for the map
         * @param v3   the value for k3
         * @param k4   a key for the map
         * @param v4   the value for k4
         * @param k5   a key for the map
         * @param v5   the value for k5
         * @param k6   a key for the map
         * @param v6   the value for k6
         * @param k7   a key for the map
         * @param v7   the value for k7
         * @param k8   a key for the map
         * @param v8   the value for k8
         * @param k9   a key for the map
         * @param v9   the value for k9
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2, K k3, V2 v3, K k4, V2 v4, K k5, V2 v5, K k6, V2 v6, K k7, V2 v7, K k8, V2 v8, K k9, V2 v9) {
            return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8).put(k9, v9);
        }

        /**
         * Creates a LinkedHashMultimap of the given list of key-value pairs.
         *
         * @param k1   a key for the map
         * @param v1   the value for k1
         * @param k2   a key for the map
         * @param v2   the value for k2
         * @param k3   a key for the map
         * @param v3   the value for k3
         * @param k4   a key for the map
         * @param v4   the value for k4
         * @param k5   a key for the map
         * @param v5   the value for k5
         * @param k6   a key for the map
         * @param v6   the value for k6
         * @param k7   a key for the map
         * @param v7   the value for k7
         * @param k8   a key for the map
         * @param v8   the value for k8
         * @param k9   a key for the map
         * @param v9   the value for k9
         * @param k10  a key for the map
         * @param v10  the value for k10
         * @param   The key type
         * @param  The value type
         * @return A new Multimap containing the given entries
         */
        public  LinkedHashMultimap of(K k1, V2 v1, K k2, V2 v2, K k3, V2 v3, K k4, V2 v4, K k5, V2 v5, K k6, V2 v6, K k7, V2 v7, K k8, V2 v8, K k9, V2 v9, K k10, V2 v10) {
            return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9).put(k10, v10);
        }

        /**
         * Creates a LinkedHashMultimap of the given key-value pair.
         * Returns a singleton {@code LinkedHashMultimap}, i.e. a {@code LinkedHashMultimap} of one entry.
         *
         * @param    The key type
         * @param    The value type
         * @param entry A tuple containing the key-value pair.
         * @return A new LinkedHashMultimap containing the given entry.
         */
        public  LinkedHashMultimap of(Tuple2 entry) {
            final LinkedHashMultimap e = empty();
            return e.put(entry._1, entry._2);
        }

        /**
         * Returns a {@link Collector} which may be used in conjunction with
         * {@link java.util.stream.Stream#collect(Collector)} to obtain a
         * {@link LinkedHashMultimap}.
         *
         * @param  The key type
         * @param  The value type
         * @return A {@link LinkedHashMultimap} Collector.
         */
        public  Collector, ArrayList>, Multimap> collector() {
            final Supplier>> supplier = ArrayList::new;
            final BiConsumer>, Tuple2> accumulator = ArrayList::add;
            final BinaryOperator>> combiner = (left, right) -> {
                left.addAll(right);
                return left;
            };
            return Collector.of(supplier, accumulator, combiner, this::ofEntries);
        }
    }

    /**
     * Narrows a widened {@code HashMultimap} to {@code HashMultimap}
     * by performing a type safe-cast. This is eligible because immutable/read-only
     * collections are covariant.
     *
     * @param map A {@code Map}.
     * @param  Key type
     * @param  Value type
     * @return the given {@code multimap} instance as narrowed type {@code Multimap}.
     */
    @SuppressWarnings("unchecked")
    public static  LinkedHashMultimap narrow(LinkedHashMultimap map) {
        return (LinkedHashMultimap) map;
    }

    private LinkedHashMultimap(Map> back, ContainerType containerType, SerializableSupplier> emptyContainer) {
        super(back, containerType, emptyContainer);
    }

    @Override
    protected  Map emptyMapSupplier() {
        return LinkedHashMap.empty();
    }

    @SuppressWarnings("unchecked")
    @Override
    protected  LinkedHashMultimap emptyInstance() {
        return new LinkedHashMultimap<>(LinkedHashMap.empty(), getContainerType(), emptyContainer);
    }

    @Override
    protected  LinkedHashMultimap createFromMap(Map> back) {
        return new LinkedHashMultimap<>(back, getContainerType(), emptyContainer);
    }

    @Override
    public boolean isSequential() {
        return true;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy