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

io.vavr.collection.TreeMap 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.Tuple;
import io.vavr.Tuple2;
import io.vavr.control.Option;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.*;
import java.util.stream.Collector;

/**
 * SortedMap implementation, backed by a Red/Black Tree.
 *
 * @param  Key type
 * @param  Value type
 * @author Daniel Dietrich
 */
// DEV-NOTE: use entries.min().get() in favor of iterator().next(), it is faster!
public final class TreeMap implements SortedMap, Serializable {

    private static final long serialVersionUID = 1L;

    private final RedBlackTree> entries;

    private TreeMap(RedBlackTree> entries) {
        this.entries = entries;
    }

    /**
     * Returns a {@link Collector} which may be used in conjunction with
     * {@link java.util.stream.Stream#collect(Collector)} to obtain a
     * {@link TreeMap}.
     * 

* The natural comparator is used to compare TreeMap keys. * * @param The key type * @param The value type * @return A {@link TreeMap} Collector. */ public static , V> Collector, ArrayList>, TreeMap> collector() { return createCollector(EntryComparator.natural()); } /** * Returns a {@link Collector} which may be used in conjunction with * {@link java.util.stream.Stream#collect(Collector)} to obtain a * {@link TreeMap}. * * @param The key type * @param The value type * @param keyComparator The comparator used to sort the entries by their key. * @return A {@link TreeMap} Collector. */ public static Collector, ArrayList>, TreeMap> collector(Comparator keyComparator) { return createCollector(EntryComparator.of(keyComparator)); } /** * Returns a {@link java.util.stream.Collector} which may be used in conjunction with * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link TreeMap}. *

* The natural comparator is used to compare TreeMap keys. * * @param keyMapper The key mapper * @param The key type * @param The value type * @param Initial {@link java.util.stream.Stream} elements type * @return A {@link TreeMap} Collector. */ public static , V, T extends V> Collector, TreeMap> collector( Function keyMapper) { Objects.requireNonNull(keyMapper, "key comparator is null"); Objects.requireNonNull(keyMapper, "keyMapper is null"); return createCollector(EntryComparator.natural(), keyMapper, v -> v); } /** * Returns a {@link java.util.stream.Collector} which may be used in conjunction with * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link TreeMap}. *

* The natural comparator is used to compare TreeMap keys. * * @param keyMapper The key mapper * @param valueMapper The value mapper * @param The key type * @param The value type * @param Initial {@link java.util.stream.Stream} elements type * @return A {@link TreeMap} Collector. */ public static , V, T> Collector, TreeMap> collector( Function keyMapper, Function valueMapper) { Objects.requireNonNull(keyMapper, "key comparator is null"); Objects.requireNonNull(keyMapper, "keyMapper is null"); Objects.requireNonNull(valueMapper, "valueMapper is null"); return createCollector(EntryComparator.natural(), keyMapper, valueMapper); } /** * Returns a {@link java.util.stream.Collector} which may be used in conjunction with * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link TreeMap}. * * @param keyMapper The key mapper * @param The key type * @param The value type * @param Initial {@link java.util.stream.Stream} elements type * @param keyComparator The comparator used to sort the entries by their key. * @return A {@link TreeMap} Collector. */ public static Collector, TreeMap> collector( Comparator keyComparator, Function keyMapper) { Objects.requireNonNull(keyMapper, "key comparator is null"); Objects.requireNonNull(keyMapper, "keyMapper is null"); return createCollector(EntryComparator.of(keyComparator), keyMapper, v -> v); } /** * Returns a {@link java.util.stream.Collector} which may be used in conjunction with * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link TreeMap}. * * @param keyMapper The key mapper * @param valueMapper The value mapper * @param The key type * @param The value type * @param Initial {@link java.util.stream.Stream} elements type * @param keyComparator The comparator used to sort the entries by their key. * @return A {@link TreeMap} Collector. */ public static Collector, TreeMap> collector( Comparator keyComparator, Function keyMapper, Function valueMapper) { Objects.requireNonNull(keyMapper, "key comparator is null"); Objects.requireNonNull(keyMapper, "keyMapper is null"); Objects.requireNonNull(valueMapper, "valueMapper is null"); return createCollector(EntryComparator.of(keyComparator), keyMapper, valueMapper); } /** * Returns the empty TreeMap. The underlying key comparator is the natural comparator of K. * * @param The key type * @param The value type * @return A new empty TreeMap. */ public static , V> TreeMap empty() { return new TreeMap<>(RedBlackTree.empty(EntryComparator.natural())); } /** * Returns the empty TreeMap using the given key comparator. * * @param The key type * @param The value type * @param keyComparator The comparator used to sort the entries by their key. * @return A new empty TreeMap. */ public static TreeMap empty(Comparator keyComparator) { return new TreeMap<>(RedBlackTree.empty(EntryComparator.of(keyComparator))); } /** * Narrows a widened {@code TreeMap} to {@code TreeMap} * by performing a type-safe cast. This is eligible because immutable/read-only * collections are covariant. *

* CAUTION: If {@code K} is narrowed, the underlying {@code Comparator} might fail! * * @param treeMap A {@code TreeMap}. * @param Key type * @param Value type * @return the given {@code treeMap} instance as narrowed type {@code TreeMap}. */ @SuppressWarnings("unchecked") public static TreeMap narrow(TreeMap treeMap) { return (TreeMap) treeMap; } /** * Returns a singleton {@code TreeMap}, i.e. a {@code TreeMap} of one entry. * The underlying key comparator is the natural comparator of K. * * @param The key type * @param The value type * @param entry A map entry. * @return A new TreeMap containing the given entry. */ public static , V> TreeMap of(Tuple2 entry) { Objects.requireNonNull(entry, "entry is null"); return createFromTuple(EntryComparator.natural(), entry); } /** * Returns a singleton {@code TreeMap}, i.e. a {@code TreeMap} of one entry using a specific key comparator. * * @param The key type * @param The value type * @param keyComparator The comparator used to sort the entries by their key. * @param entry A map entry. * @return A new TreeMap containing the given entry. */ public static TreeMap of(Comparator keyComparator, Tuple2 entry) { Objects.requireNonNull(entry, "entry is null"); return createFromTuple(EntryComparator.of(keyComparator), entry); } /** * Returns a {@code TreeMap}, from a source java.util.Map. * * @param map A map * @param The key type * @param The value type * @return A new Map containing the given map */ public static , V> TreeMap ofAll(java.util.Map map) { Objects.requireNonNull(map, "map is null"); return createFromMap(EntryComparator.natural(), map); } /** * Returns a {@code TreeMap}, 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 Map */ public static , V> TreeMap ofAll(java.util.stream.Stream stream, Function keyMapper, Function valueMapper) { return Maps.ofStream(TreeMap. empty(), stream, keyMapper, valueMapper); } /** * Returns a {@code TreeMap}, from entries mapped from stream. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map */ public static TreeMap ofAll(Comparator keyComparator, java.util.stream.Stream stream, Function keyMapper, Function valueMapper) { return Maps.ofStream(empty(keyComparator), stream, keyMapper, valueMapper); } /** * Returns a {@code TreeMap}, 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 Map */ public static , V> TreeMap ofAll(java.util.stream.Stream stream, Function> entryMapper) { return Maps.ofStream(TreeMap. empty(), stream, entryMapper); } /** * Returns a {@code TreeMap}, from entries mapped from stream. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map */ public static TreeMap ofAll(Comparator keyComparator, java.util.stream.Stream stream, Function> entryMapper) { return Maps.ofStream(empty(keyComparator), stream, entryMapper); } /** * Returns a {@code TreeMap}, from a source java.util.Map. * * @param keyComparator The comparator used to sort the entries by their key. * @param map A map * @param The key type * @param The value type * @return A new Map containing the given map */ public static TreeMap ofAll(Comparator keyComparator, java.util.Map map) { Objects.requireNonNull(map, "map is null"); return createFromMap(EntryComparator.of(keyComparator), map); } /** * Returns a singleton {@code TreeMap}, i.e. a {@code TreeMap} of one element. * * @param key A singleton map key. * @param value A singleton map value. * @param The key type * @param The value type * @return A new Map containing the given entry */ public static , V> TreeMap of(K key, V value) { return createFromPairs(EntryComparator.natural(), key, value); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(K k1, V v1, K k2, V v2) { return createFromPairs(EntryComparator.natural(), k1, v1, k2, v2); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(K k1, V v1, K k2, V v2, K k3, V v3) { return createFromPairs(EntryComparator.natural(), k1, v1, k2, v2, k3, v3); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { return createFromPairs(EntryComparator.natural(), k1, v1, k2, v2, k3, v3, k4, v4); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { return createFromPairs(EntryComparator.natural(), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(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 createFromPairs(EntryComparator.natural(), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(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 createFromPairs(EntryComparator.natural(), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(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 createFromPairs(EntryComparator.natural(), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(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 createFromPairs(EntryComparator.natural(), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9); } /** * Creates a {@code TreeMap} 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 Map containing the given entries */ public static , V> TreeMap of(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 createFromPairs(EntryComparator.natural(), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10); } /** * Returns a singleton {@code TreeMap}, i.e. a {@code TreeMap} of one element. * * @param keyComparator The comparator used to sort the entries by their key. * @param key A singleton map key. * @param value A singleton map value. * @param The key type * @param The value type * @return A new Map containing the given entry */ public static TreeMap of(Comparator keyComparator, K key, V value) { return createFromPairs(EntryComparator.of(keyComparator), key, value); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, K k1, V v1, K k2, V v2) { return createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, K k1, V v1, K k2, V v2, K k3, V v3) { return createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2, k3, v3); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { return createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2, k3, v3, k4, v4); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { return createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, 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 createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, 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 createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, 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 createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, 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 createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9); } /** * Creates a {@code TreeMap} of the given list of key-value pairs. * * @param keyComparator The comparator used to sort the entries by their key. * @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 Map containing the given entries */ public static TreeMap of(Comparator keyComparator, 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 createFromPairs(EntryComparator.of(keyComparator), k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10); } /** * Returns a TreeMap 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 keyComparator The comparator used to sort the entries by their key * @param n The number of elements in the TreeMap * @param f The Function computing element values * @return A TreeMap consisting of elements {@code f(0),f(1), ..., f(n - 1)} * @throws NullPointerException if {@code keyComparator} or {@code f} are null */ public static TreeMap tabulate(Comparator keyComparator, int n, Function> f) { Objects.requireNonNull(f, "f is null"); return createTreeMap(EntryComparator.of(keyComparator), Collections.tabulate(n, f)); } /** * Returns a TreeMap containing {@code n} values of a given Function {@code f} * over a range of integer values from 0 to {@code n - 1}. * The underlying key comparator is the natural comparator of K. * * @param The key type * @param The value type * @param n The number of elements in the TreeMap * @param f The Function computing element values * @return A TreeMap consisting of elements {@code f(0),f(1), ..., f(n - 1)} * @throws NullPointerException if {@code f} is null */ public static , V> TreeMap tabulate(int n, Function> f) { Objects.requireNonNull(f, "f is null"); return createTreeMap(EntryComparator.natural(), Collections.tabulate(n, f)); } /** * Returns a TreeMap containing tuples returned by {@code n} calls to a given Supplier {@code s}. * * @param The key type * @param The value type * @param keyComparator The comparator used to sort the entries by their key * @param n The number of elements in the TreeMap * @param s The Supplier computing element values * @return A TreeMap of size {@code n}, where each element contains the result supplied by {@code s}. * @throws NullPointerException if {@code keyComparator} or {@code s} are null */ @SuppressWarnings("unchecked") public static TreeMap fill(Comparator keyComparator, int n, Supplier> s) { Objects.requireNonNull(s, "s is null"); return createTreeMap(EntryComparator.of(keyComparator), Collections.fill(n, s)); } /** * Returns a TreeMap containing tuples returned by {@code n} calls to a given Supplier {@code s}. * The underlying key comparator is the natural comparator of K. * * @param The key type * @param The value type * @param n The number of elements in the TreeMap * @param s The Supplier computing element values * @return A TreeMap of size {@code n}, where each element contains the result supplied by {@code s}. * @throws NullPointerException if {@code s} is null */ public static , V> TreeMap fill(int n, Supplier> s) { Objects.requireNonNull(s, "s is null"); return createTreeMap(EntryComparator.natural(), Collections.fill(n, s)); } /** * Creates a {@code TreeMap} of the given entries using the natural key comparator. * * @param The key type * @param The value type * @param entries Map entries * @return A new TreeMap containing the given entries. */ @SuppressWarnings("varargs") @SafeVarargs public static , V> TreeMap ofEntries(Tuple2... entries) { return createFromTuples(EntryComparator.natural(), entries); } /** * Creates a {@code TreeMap} of the given entries using the given key comparator. * * @param The key type * @param The value type * @param keyComparator The comparator used to sort the entries by their key. * @param entries Map entries * @return A new TreeMap containing the given entries. */ @SuppressWarnings({ "unchecked", "varargs" }) @SafeVarargs public static TreeMap ofEntries(Comparator keyComparator, Tuple2... entries) { return createFromTuples(EntryComparator.of(keyComparator), entries); } /** * Creates a {@code TreeMap} of the given entries using the natural key comparator. * * @param The key type * @param The value type * @param entries Map entries * @return A new TreeMap containing the given entries. */ @SuppressWarnings("varargs") @SafeVarargs public static , V> TreeMap ofEntries(java.util.Map.Entry... entries) { return createFromMapEntries(EntryComparator.natural(), entries); } /** * Creates a {@code TreeMap} of the given entries using the given key comparator. * * @param The key type * @param The value type * @param keyComparator The comparator used to sort the entries by their key. * @param entries Map entries * @return A new TreeMap containing the given entries. */ @SuppressWarnings("varargs") @SafeVarargs public static TreeMap ofEntries(Comparator keyComparator, java.util.Map.Entry... entries) { return createFromMapEntries(EntryComparator.of(keyComparator), entries); } /** * Creates a {@code TreeMap} of the given entries. * * @param The key type * @param The value type * @param entries Map entries * @return A new TreeMap containing the given entries. */ public static , V> TreeMap ofEntries(Iterable> entries) { return createTreeMap(EntryComparator.natural(), entries); } /** * Creates a {@code TreeMap} of the given entries. * * @param The key type * @param The value type * @param keyComparator The comparator used to sort the entries by their key. * @param entries Map entries * @return A new TreeMap containing the given entries. */ @SuppressWarnings("unchecked") public static TreeMap ofEntries(Comparator keyComparator, Iterable> entries) { return createTreeMap(EntryComparator.of(keyComparator), entries); } // -- TreeMap API @Override public TreeMap bimap(Function keyMapper, Function valueMapper) { return bimap(this, EntryComparator.natural(), keyMapper, valueMapper); } @Override public TreeMap bimap(Comparator keyComparator, Function keyMapper, Function valueMapper) { return bimap(this, EntryComparator.of(keyComparator), keyMapper, valueMapper); } @Override public Tuple2> computeIfAbsent(K key, Function mappingFunction) { return Maps.computeIfAbsent(this, key, mappingFunction); } @Override public Tuple2, TreeMap> computeIfPresent(K key, BiFunction remappingFunction) { return Maps.computeIfPresent(this, key, remappingFunction); } @Override public boolean containsKey(K key) { return entries.contains(new Tuple2<>(key, /*ignored*/null)); } @Override public TreeMap distinct() { return Maps.distinct(this); } @Override public TreeMap distinctBy(Comparator> comparator) { return Maps.distinctBy(this, this::createFromEntries, comparator); } @Override public TreeMap distinctBy(Function, ? extends U> keyExtractor) { return Maps.distinctBy(this, this::createFromEntries, keyExtractor); } @Override public TreeMap drop(int n) { return Maps.drop(this, this::createFromEntries, this::emptyInstance, n); } @Override public TreeMap dropRight(int n) { return Maps.dropRight(this, this::createFromEntries, this::emptyInstance, n); } @Override public TreeMap dropUntil(Predicate> predicate) { return Maps.dropUntil(this, this::createFromEntries, predicate); } @Override public TreeMap dropWhile(Predicate> predicate) { return Maps.dropWhile(this, this::createFromEntries, predicate); } @Override public TreeMap filter(BiPredicate predicate) { return Maps.filter(this, this::createFromEntries, predicate); } @Override public TreeMap reject(BiPredicate predicate) { return Maps.reject(this, this::createFromEntries, predicate); } @Override public TreeMap filter(Predicate> predicate) { return Maps.filter(this, this::createFromEntries, predicate); } @Override public TreeMap reject(Predicate> predicate) { return Maps.reject(this, this::createFromEntries, predicate); } @Override public TreeMap filterKeys(Predicate predicate) { return Maps.filterKeys(this, this::createFromEntries, predicate); } @Override public TreeMap rejectKeys(Predicate predicate) { return Maps.rejectKeys(this, this::createFromEntries, predicate); } @Override public TreeMap filterValues(Predicate predicate) { return Maps.filterValues(this, this::createFromEntries, predicate); } @Override public TreeMap rejectValues(Predicate predicate) { return Maps.rejectValues(this, this::createFromEntries, predicate); } @Override public TreeMap flatMap(BiFunction>> mapper) { return flatMap(this, EntryComparator.natural(), mapper); } @Override public TreeMap flatMap(Comparator keyComparator, BiFunction>> mapper) { return flatMap(this, EntryComparator.of(keyComparator), mapper); } @Override public Option get(K key) { final V ignored = null; return entries.find(new Tuple2<>(key, ignored)).map(Tuple2::_2); } @Override public V getOrElse(K key, V defaultValue) { return get(key).getOrElse(defaultValue); } @Override public Map> groupBy(Function, ? extends C> classifier) { return Maps.groupBy(this, this::createFromEntries, classifier); } @Override public Iterator> grouped(int size) { return Maps.grouped(this, this::createFromEntries, size); } @Override public Tuple2 head() { if (isEmpty()) { throw new NoSuchElementException("head of empty TreeMap"); } else { return entries.min().get(); } } @Override public Tuple2 last() { if (isEmpty()) { throw new NoSuchElementException("last of empty TreeMap"); } else { return entries.max().get(); } } @Override public TreeMap init() { if (isEmpty()) { throw new UnsupportedOperationException("init of empty TreeMap"); } else { final Tuple2 max = entries.max().get(); return new TreeMap<>(entries.delete(max)); } } @Override public Option> initOption() { return Maps.initOption(this); } /** * An {@code TreeMap}'s value is computed synchronously. * * @return false */ @Override public boolean isAsync() { return false; } @Override public boolean isEmpty() { return entries.isEmpty(); } /** * An {@code TreeMap}'s value is computed eagerly. * * @return false */ @Override public boolean isLazy() { return false; } @Override public Iterator> iterator() { return entries.iterator(); } @Override public SortedSet keySet() { return TreeSet.ofAll(comparator(), iterator().map(Tuple2::_1)); } @Override public TreeMap map(BiFunction> mapper) { return map(this, EntryComparator.natural(), mapper); } @Override public TreeMap map(Comparator keyComparator, BiFunction> mapper) { Objects.requireNonNull(keyComparator, "keyComparator is null"); return map(this, EntryComparator.of(keyComparator), mapper); } @Override public TreeMap mapKeys(Function keyMapper) { Objects.requireNonNull(keyMapper, "keyMapper is null"); return map((k, v) -> Tuple.of(keyMapper.apply(k), v)); } @Override public TreeMap mapKeys(Function keyMapper, BiFunction valueMerge) { final Comparator comparator = Comparators.naturalComparator(); return Collections.mapKeys(this, TreeMap. empty(comparator), keyMapper, valueMerge); } @Override public TreeMap mapValues(Function valueMapper) { Objects.requireNonNull(valueMapper, "valueMapper is null"); return map(comparator(), (k, v) -> Tuple.of(k, valueMapper.apply(v))); } @Override public TreeMap merge(Map that) { return Maps.merge(this, this::createFromEntries, that); } @Override public TreeMap merge(Map that, BiFunction collisionResolution) { return Maps.merge(this, this::createFromEntries, that, collisionResolution); } /** * Returns this {@code TreeMap} if it is nonempty, * otherwise {@code TreeMap} created from iterable, using existing comparator. * * @param other An alternative {@code Traversable} * @return this {@code TreeMap} if it is nonempty, * otherwise {@code TreeMap} created from iterable, using existing comparator. */ @Override public TreeMap orElse(Iterable> other) { return isEmpty() ? ofEntries(comparator(), other) : this; } /** * Returns this {@code TreeMap} if it is nonempty, * otherwise {@code TreeMap} created from result of evaluating supplier, using existing comparator. * * @param supplier An alternative {@code Traversable} * @return this {@code TreeMap} if it is nonempty, * otherwise {@code TreeMap} created from result of evaluating supplier, using existing comparator. */ @Override public TreeMap orElse(Supplier>> supplier) { return isEmpty() ? ofEntries(comparator(), supplier.get()) : this; } @Override public Tuple2, TreeMap> partition(Predicate> predicate) { return Maps.partition(this, this::createFromEntries, predicate); } @Override public TreeMap peek(Consumer> action) { return Maps.peek(this, action); } @Override public TreeMap put(K key, U value, BiFunction merge) { return Maps.put(this, key, value, merge); } @Override public TreeMap put(K key, V value) { return new TreeMap<>(entries.insert(new Tuple2<>(key, value))); } @Override public TreeMap put(Tuple2 entry) { return Maps.put(this, entry); } @Override public TreeMap put(Tuple2 entry, BiFunction merge) { return Maps.put(this, entry, merge); } @Override public TreeMap remove(K key) { final V ignored = null; final Tuple2 entry = new Tuple2<>(key, ignored); if (entries.contains(entry)) { return new TreeMap<>(entries.delete(entry)); } else { return this; } } @Override @Deprecated public TreeMap removeAll(BiPredicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return reject(predicate); } @Override public TreeMap removeAll(Iterable keys) { final V ignored = null; RedBlackTree> removed = entries; for (K key : keys) { final Tuple2 entry = new Tuple2<>(key, ignored); if (removed.contains(entry)) { removed = removed.delete(entry); } } if (removed.size() == entries.size()) { return this; } else { return new TreeMap<>(removed); } } @Override @Deprecated public TreeMap removeKeys(Predicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return rejectKeys(predicate); } @Override @Deprecated public TreeMap removeValues(Predicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return rejectValues(predicate); } @Override public TreeMap replace(Tuple2 currentElement, Tuple2 newElement) { return Maps.replace(this, currentElement, newElement); } @Override public TreeMap replaceAll(Tuple2 currentElement, Tuple2 newElement) { return Maps.replaceAll(this, currentElement, newElement); } @Override public TreeMap replaceValue(K key, V value) { return Maps.replaceValue(this, key, value); } @Override public TreeMap replace(K key, V oldValue, V newValue) { return Maps.replace(this, key, oldValue, newValue); } @Override public TreeMap replaceAll(BiFunction function) { return Maps.replaceAll(this, function); } @Override public TreeMap retainAll(Iterable> elements) { Objects.requireNonNull(elements, "elements is null"); RedBlackTree> tree = RedBlackTree.empty(entries.comparator()); for (Tuple2 entry : elements) { if (contains(entry)) { tree = tree.insert(entry); } } return new TreeMap<>(tree); } @Override public TreeMap scan( Tuple2 zero, BiFunction, ? super Tuple2, ? extends Tuple2> operation) { return Maps.scan(this, zero, operation, this::createFromEntries); } @Override public int size() { return entries.size(); } @Override public Iterator> slideBy(Function, ?> classifier) { return Maps.slideBy(this, this::createFromEntries, classifier); } @Override public Iterator> sliding(int size) { return Maps.sliding(this, this::createFromEntries, size); } @Override public Iterator> sliding(int size, int step) { return Maps.sliding(this, this::createFromEntries, size, step); } @Override public Tuple2, TreeMap> span(Predicate> predicate) { return Maps.span(this, this::createFromEntries, predicate); } @Override public TreeMap tail() { if (isEmpty()) { throw new UnsupportedOperationException("tail of empty TreeMap"); } else { final Tuple2 min = entries.min().get(); return new TreeMap<>(entries.delete(min)); } } @Override public Option> tailOption() { return Maps.tailOption(this); } @Override public TreeMap take(int n) { return Maps.take(this, this::createFromEntries, n); } @Override public TreeMap takeRight(int n) { return Maps.takeRight(this, this::createFromEntries, n); } @Override public TreeMap takeUntil(Predicate> predicate) { return Maps.takeUntil(this, this::createFromEntries, predicate); } @Override public TreeMap takeWhile(Predicate> predicate) { return Maps.takeWhile(this, this::createFromEntries, predicate); } @Override public java.util.TreeMap toJavaMap() { return toJavaMap(() -> new java.util.TreeMap<>(comparator()), t -> t); } @Override public Seq values() { return map(Tuple2::_2); } // -- Object @Override public boolean equals(Object o) { return Collections.equals(this, o); } @Override public int hashCode() { return Collections.hashUnordered(this); } @Override public String stringPrefix() { return "TreeMap"; } @Override public String toString() { return mkString(stringPrefix() + "(", ", ", ")"); } // -- private helpers private static TreeMap bimap(TreeMap map, EntryComparator entryComparator, Function keyMapper, Function valueMapper) { Objects.requireNonNull(keyMapper, "keyMapper is null"); Objects.requireNonNull(valueMapper, "valueMapper is null"); return createTreeMap(entryComparator, map.entries, entry -> entry.map(keyMapper, valueMapper)); } private static TreeMap flatMap(TreeMap map, EntryComparator entryComparator, BiFunction>> mapper) { Objects.requireNonNull(mapper, "mapper is null"); return createTreeMap(entryComparator, map.entries.iterator().flatMap(entry -> mapper.apply(entry._1, entry._2))); } private static TreeMap map(TreeMap map, EntryComparator entryComparator, BiFunction> mapper) { Objects.requireNonNull(mapper, "mapper is null"); return createTreeMap(entryComparator, map.entries, entry -> entry.map(mapper)); } // -- internal factory methods private static Collector, ArrayList>, TreeMap> createCollector(EntryComparator entryComparator) { final Supplier>> supplier = ArrayList::new; final BiConsumer>, Tuple2> accumulator = ArrayList::add; final BinaryOperator>> combiner = (left, right) -> { left.addAll(right); return left; }; final Function>, TreeMap> finisher = list -> createTreeMap(entryComparator, list); return Collector.of(supplier, accumulator, combiner, finisher); } private static Collector, TreeMap> createCollector( EntryComparator entryComparator, Function keyMapper, Function valueMapper) { final Supplier> supplier = ArrayList::new; final BiConsumer, T> accumulator = ArrayList::add; final BinaryOperator> combiner = (left, right) -> { left.addAll(right); return left; }; final Function, TreeMap> finisher = arr -> createTreeMap(entryComparator, Iterator.ofAll(arr) .map(t -> Tuple.of(keyMapper.apply(t), valueMapper.apply(t)))); return Collector.of(supplier, accumulator, combiner, finisher); } @SuppressWarnings("unchecked") private static TreeMap createTreeMap(EntryComparator entryComparator, Iterable> entries) { Objects.requireNonNull(entries, "entries is null"); RedBlackTree> tree = RedBlackTree.empty(entryComparator); for (Tuple2 entry : (Iterable>) entries) { tree = tree.insert(entry); } return new TreeMap<>(tree); } private static TreeMap createTreeMap(EntryComparator entryComparator, Iterable> entries, Function, Tuple2> entryMapper) { RedBlackTree> tree = RedBlackTree.empty(entryComparator); for (Tuple2 entry : entries) { tree = tree.insert(entryMapper.apply(entry)); } return new TreeMap<>(tree); } @SuppressWarnings("unchecked") private static TreeMap createFromMap(EntryComparator entryComparator, java.util.Map map) { Objects.requireNonNull(map, "map is null"); RedBlackTree> tree = RedBlackTree.empty(entryComparator); for (java.util.Map.Entry entry : ((java.util.Map) map).entrySet()) { tree = tree.insert(Tuple.of(entry.getKey(), entry.getValue())); } return new TreeMap<>(tree); } @SuppressWarnings("unchecked") private static TreeMap createFromTuple(EntryComparator entryComparator, Tuple2 entry) { Objects.requireNonNull(entry, "entry is null"); return new TreeMap<>(RedBlackTree.of(entryComparator, (Tuple2) entry)); } @SuppressWarnings("unchecked") private static TreeMap createFromTuples(EntryComparator entryComparator, Tuple2... entries) { Objects.requireNonNull(entries, "entries is null"); RedBlackTree> tree = RedBlackTree.empty(entryComparator); for (Tuple2 entry : entries) { tree = tree.insert((Tuple2) entry); } return new TreeMap<>(tree); } @SafeVarargs private static TreeMap createFromMapEntries(EntryComparator entryComparator, java.util.Map.Entry... entries) { Objects.requireNonNull(entries, "entries is null"); RedBlackTree> tree = RedBlackTree.empty(entryComparator); for (java.util.Map.Entry entry : entries) { final K key = entry.getKey(); final V value = entry.getValue(); tree = tree.insert(Tuple.of(key, value)); } return new TreeMap<>(tree); } @SuppressWarnings("unchecked") private static TreeMap createFromPairs(EntryComparator entryComparator, Object... pairs) { RedBlackTree> tree = RedBlackTree.empty(entryComparator); for (int i = 0; i < pairs.length; i += 2) { final K key = (K) pairs[i]; final V value = (V) pairs[i + 1]; tree = tree.insert(Tuple.of(key, value)); } return new TreeMap<>(tree); } private TreeMap createFromEntries(Iterable> tuples) { return createTreeMap((EntryComparator) entries.comparator(), tuples); } private TreeMap emptyInstance() { return isEmpty() ? this : new TreeMap<>(entries.emptyInstance()); } @Override public Comparator comparator() { return ((EntryComparator) entries.comparator()).keyComparator(); } // -- internal types private interface EntryComparator extends Comparator>, Serializable { long serialVersionUID = 1L; static EntryComparator of(Comparator keyComparator) { Objects.requireNonNull(keyComparator, "keyComparator is null"); return new Specific<>(keyComparator); } static EntryComparator natural() { return Natural.instance(); } Comparator keyComparator(); // -- internal impls final class Specific implements EntryComparator { private static final long serialVersionUID = 1L; private final Comparator keyComparator; @SuppressWarnings("unchecked") Specific(Comparator keyComparator) { this.keyComparator = (Comparator) keyComparator; } @Override public int compare(Tuple2 e1, Tuple2 e2) { return keyComparator.compare(e1._1, e2._1); } @Override public Comparator keyComparator() { return keyComparator; } } final class Natural implements EntryComparator { private static final long serialVersionUID = 1L; private static final Natural INSTANCE = new Natural<>(); // hidden private Natural() { } @SuppressWarnings("unchecked") public static Natural instance() { return (Natural) INSTANCE; } @SuppressWarnings("unchecked") @Override public int compare(Tuple2 e1, Tuple2 e2) { final K key1 = e1._1; final K key2 = e2._1; return ((Comparable) key1).compareTo(key2); } @Override public Comparator keyComparator() { return Comparators.naturalComparator(); } @Override public boolean equals(Object obj) { return obj instanceof Natural; } @Override public int hashCode() { return 1; } /** * Instance control for object serialization. * * @return The singleton instance of NaturalEntryComparator. * @see java.io.Serializable */ private Object readResolve() { return INSTANCE; } } } }