/* __ __ __ __ __ ___ * \ \ / / \ \ / / __/ * \ \/ / /\ \ \/ / / * \____/__/ \__\____/__/.ɪᴏ * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ */ 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 <K> Key type * @param <V> Value type * @author Daniel Dietrich */ // DEV-NOTE: use entries.min().get() in favor of iterator().next(), it is faster! public final class TreeMap<K, V> implements SortedMap<K, V>, Serializable { private static final long serialVersionUID = 1L; private final RedBlackTree<Tuple2<K, V>> entries; private TreeMap(RedBlackTree<Tuple2<K, V>> 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}. * <p> * The natural comparator is used to compare TreeMap keys. * * @param <K> The key type * @param <V> The value type * @return A {@link TreeMap} Collector. */ public static <K extends Comparable<? super K>, V> Collector<Tuple2<K, V>, ArrayList<Tuple2<K, V>>, TreeMap<K, V>> 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 <K> The key type * @param <V> The value type * @param keyComparator The comparator used to sort the entries by their key. * @return A {@link TreeMap} Collector. */ public static <K, V> Collector<Tuple2<K, V>, ArrayList<Tuple2<K, V>>, TreeMap<K, V>> collector(Comparator<? super K> keyComparator) { return createCollector(EntryComparator.of(keyComparator)); } /** * Returns the empty TreeMap. The underlying key comparator is the natural comparator of K. * * @param <K> The key type * @param <V> The value type * @return A new empty TreeMap. */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> empty() { return new TreeMap<>(RedBlackTree.empty(EntryComparator.natural())); } /** * Returns the empty TreeMap using the given key comparator. * * @param <K> The key type * @param <V> The value type * @param keyComparator The comparator used to sort the entries by their key. * @return A new empty TreeMap. */ public static <K, V> TreeMap<K, V> empty(Comparator<? super K> keyComparator) { return new TreeMap<>(RedBlackTree.empty(EntryComparator.of(keyComparator))); } /** * Narrows a widened {@code TreeMap<? extends K, ? extends V>} to {@code TreeMap<K, V>} * by performing a type-safe cast. This is eligible because immutable/read-only * collections are covariant. * <p> * CAUTION: If {@code K} is narrowed, the underlying {@code Comparator} might fail! * * @param treeMap A {@code TreeMap}. * @param <K> Key type * @param <V> Value type * @return the given {@code treeMap} instance as narrowed type {@code TreeMap<K, V>}. */ @SuppressWarnings("unchecked") public static <K, V> TreeMap<K, V> narrow(TreeMap<? extends K, ? extends V> treeMap) { return (TreeMap<K, V>) 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 <K> The key type * @param <V> The value type * @param entry A map entry. * @return A new TreeMap containing the given entry. */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> of(Tuple2<? extends K, ? extends V> 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 <K> The key type * @param <V> 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 <K, V> TreeMap<K, V> of(Comparator<? super K> keyComparator, Tuple2<? extends K, ? extends V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given map */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> ofAll(java.util.Map<? extends K, ? extends V> 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 <T> The stream element type * @param <K> The key type * @param <V> The value type * @return A new Map */ public static <T, K extends Comparable<? super K>, V> TreeMap<K, V> ofAll(java.util.stream.Stream<? extends T> stream, Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) { return Maps.ofStream(TreeMap.<K, V> 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 <T> The stream element type * @param <K> The key type * @param <V> The value type * @return A new Map */ public static <T, K, V> TreeMap<K, V> ofAll(Comparator<? super K> keyComparator, java.util.stream.Stream<? extends T> stream, Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> 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 <T> The stream element type * @param <K> The key type * @param <V> The value type * @return A new Map */ public static <T, K extends Comparable<? super K>, V> TreeMap<K, V> ofAll(java.util.stream.Stream<? extends T> stream, Function<? super T, Tuple2<? extends K, ? extends V>> entryMapper) { return Maps.ofStream(TreeMap.<K, V> 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 <T> The stream element type * @param <K> The key type * @param <V> The value type * @return A new Map */ public static <T, K, V> TreeMap<K, V> ofAll(Comparator<? super K> keyComparator, java.util.stream.Stream<? extends T> stream, Function<? super T, Tuple2<? extends K, ? extends V>> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given map */ public static <K, V> TreeMap<K, V> ofAll(Comparator<? super K> keyComparator, java.util.Map<? extends K, ? extends V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entry */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entry */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> The value type * @return A new Map containing the given entries */ public static <K, V> TreeMap<K, V> of(Comparator<? super K> 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 <K> The key type * @param <V> 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 <K, V> TreeMap<K, V> tabulate(Comparator<? super K> keyComparator, int n, Function<? super Integer, ? extends Tuple2<? extends K, ? extends V>> 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 <K> The key type * @param <V> 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 <K extends Comparable<? super K>, V> TreeMap<K, V> tabulate(int n, Function<? super Integer, ? extends Tuple2<? extends K, ? extends V>> f) { Objects.requireNonNull(f, "f is null"); return createTreeMap(EntryComparator.natural(), Collections.tabulate(n, f)); } /** * Returns a TreeMap containing {@code n} values supplied by a given Supplier {@code s}. * * @param <K> The key type * @param <V> 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 <K, V> TreeMap<K, V> fill(Comparator<? super K> keyComparator, int n, Supplier<? extends Tuple2<? extends K, ? extends V>> s) { Objects.requireNonNull(s, "s is null"); return createTreeMap(EntryComparator.of(keyComparator), Collections.fill(n, s)); } /** * Returns a TreeMap containing {@code n} values supplied by a given Supplier {@code s}. * The underlying key comparator is the natural comparator of K. * * @param <K> The key type * @param <V> 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 <K extends Comparable<? super K>, V> TreeMap<K, V> fill(int n, Supplier<? extends Tuple2<? extends K, ? extends V>> 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 <K> The key type * @param <V> The value type * @param entries Map entries * @return A new TreeMap containing the given entries. */ @SuppressWarnings("varargs") @SafeVarargs public static <K extends Comparable<? super K>, V> TreeMap<K, V> ofEntries(Tuple2<? extends K, ? extends V>... entries) { return createFromTuples(EntryComparator.natural(), entries); } /** * Creates a {@code TreeMap} of the given entries using the given key comparator. * * @param <K> The key type * @param <V> 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 <K, V> TreeMap<K, V> ofEntries(Comparator<? super K> keyComparator, Tuple2<? extends K, ? extends V>... entries) { return createFromTuples(EntryComparator.of(keyComparator), entries); } /** * Creates a {@code TreeMap} of the given entries using the natural key comparator. * * @param <K> The key type * @param <V> The value type * @param entries Map entries * @return A new TreeMap containing the given entries. */ @SuppressWarnings("varargs") @SafeVarargs public static <K extends Comparable<? super K>, V> TreeMap<K, V> ofEntries(java.util.Map.Entry<? extends K, ? extends V>... entries) { return createFromMapEntries(EntryComparator.natural(), entries); } /** * Creates a {@code TreeMap} of the given entries using the given key comparator. * * @param <K> The key type * @param <V> 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 <K, V> TreeMap<K, V> ofEntries(Comparator<? super K> keyComparator, java.util.Map.Entry<? extends K, ? extends V>... entries) { return createFromMapEntries(EntryComparator.of(keyComparator), entries); } /** * Creates a {@code TreeMap} of the given entries. * * @param <K> The key type * @param <V> The value type * @param entries Map entries * @return A new TreeMap containing the given entries. */ public static <K extends Comparable<? super K>, V> TreeMap<K, V> ofEntries(Iterable<? extends Tuple2<? extends K, ? extends V>> entries) { return createTreeMap(EntryComparator.natural(), entries); } /** * Creates a {@code TreeMap} of the given entries. * * @param <K> The key type * @param <V> 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 <K, V> TreeMap<K, V> ofEntries(Comparator<? super K> keyComparator, Iterable<? extends Tuple2<? extends K, ? extends V>> entries) { return createTreeMap(EntryComparator.of(keyComparator), entries); } // -- TreeMap API @Override public <K2, V2> TreeMap<K2, V2> bimap(Function<? super K, ? extends K2> keyMapper, Function<? super V, ? extends V2> valueMapper) { return bimap(this, EntryComparator.natural(), keyMapper, valueMapper); } @Override public <K2, V2> TreeMap<K2, V2> bimap(Comparator<? super K2> keyComparator, Function<? super K, ? extends K2> keyMapper, Function<? super V, ? extends V2> valueMapper) { return bimap(this, EntryComparator.of(keyComparator), keyMapper, valueMapper); } @Override public Tuple2<V, TreeMap<K, V>> computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { return Maps.computeIfAbsent(this, key, mappingFunction); } @Override public Tuple2<Option<V>, TreeMap<K, V>> computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { return Maps.computeIfPresent(this, key, remappingFunction); } @Override public boolean containsKey(K key) { return entries.contains(new Tuple2<>(key, /*ignored*/null)); } @Override public TreeMap<K, V> distinct() { return Maps.distinct(this); } @Override public TreeMap<K, V> distinctBy(Comparator<? super Tuple2<K, V>> comparator) { return Maps.distinctBy(this, this::createFromEntries, comparator); } @Override public <U> TreeMap<K, V> distinctBy(Function<? super Tuple2<K, V>, ? extends U> keyExtractor) { return Maps.distinctBy(this, this::createFromEntries, keyExtractor); } @Override public TreeMap<K, V> drop(int n) { return Maps.drop(this, this::createFromEntries, this::emptyInstance, n); } @Override public TreeMap<K, V> dropRight(int n) { return Maps.dropRight(this, this::createFromEntries, this::emptyInstance, n); } @Override public TreeMap<K, V> dropUntil(Predicate<? super Tuple2<K, V>> predicate) { return Maps.dropUntil(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> dropWhile(Predicate<? super Tuple2<K, V>> predicate) { return Maps.dropWhile(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> filter(BiPredicate<? super K, ? super V> predicate) { return Maps.filter(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> filter(Predicate<? super Tuple2<K, V>> predicate) { return Maps.filter(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> filterKeys(Predicate<? super K> predicate) { return Maps.filterKeys(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> filterValues(Predicate<? super V> predicate) { return Maps.filterValues(this, this::createFromEntries, predicate); } @Override public <K2, V2> TreeMap<K2, V2> flatMap(BiFunction<? super K, ? super V, ? extends Iterable<Tuple2<K2, V2>>> mapper) { return flatMap(this, EntryComparator.natural(), mapper); } @Override public <K2, V2> TreeMap<K2, V2> flatMap(Comparator<? super K2> keyComparator, BiFunction<? super K, ? super V, ? extends Iterable<Tuple2<K2, V2>>> mapper) { return flatMap(this, EntryComparator.of(keyComparator), mapper); } @Override public Option<V> 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 <C> Map<C, TreeMap<K, V>> groupBy(Function<? super Tuple2<K, V>, ? extends C> classifier) { return Maps.groupBy(this, this::createFromEntries, classifier); } @Override public Iterator<TreeMap<K, V>> grouped(int size) { return Maps.grouped(this, this::createFromEntries, size); } @Override public Tuple2<K, V> head() { if (isEmpty()) { throw new NoSuchElementException("head of empty TreeMap"); } else { return entries.min().get(); } } @Override public TreeMap<K, V> init() { if (isEmpty()) { throw new UnsupportedOperationException("init of empty TreeMap"); } else { final Tuple2<K, V> max = entries.max().get(); return new TreeMap<>(entries.delete(max)); } } @Override public Option<TreeMap<K, V>> 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<Tuple2<K, V>> iterator() { return entries.iterator(); } @Override public SortedSet<K> keySet() { return TreeSet.ofAll(comparator(), iterator().map(Tuple2::_1)); } @Override public <K2, V2> TreeMap<K2, V2> map(BiFunction<? super K, ? super V, Tuple2<K2, V2>> mapper) { return map(this, EntryComparator.natural(), mapper); } @Override public <K2, V2> TreeMap<K2, V2> map(Comparator<? super K2> keyComparator, BiFunction<? super K, ? super V, Tuple2<K2, V2>> mapper) { Objects.requireNonNull(keyComparator, "keyComparator is null"); return map(this, EntryComparator.of(keyComparator), mapper); } @Override public <K2> TreeMap<K2, V> mapKeys(Function<? super K, ? extends K2> keyMapper) { Objects.requireNonNull(keyMapper, "keyMapper is null"); return map((k, v) -> Tuple.of(keyMapper.apply(k), v)); } @Override public <K2> TreeMap<K2, V> mapKeys(Function<? super K, ? extends K2> keyMapper, BiFunction<? super V, ? super V, ? extends V> valueMerge) { final Comparator<K2> comparator = Comparators.naturalComparator(); return Collections.mapKeys(this, TreeMap.<K2, V> empty(comparator), keyMapper, valueMerge); } @Override public <W> TreeMap<K, W> mapValues(Function<? super V, ? extends W> valueMapper) { Objects.requireNonNull(valueMapper, "valueMapper is null"); return map(comparator(), (k, v) -> Tuple.of(k, valueMapper.apply(v))); } @Override public TreeMap<K, V> merge(Map<? extends K, ? extends V> that) { return Maps.merge(this, this::createFromEntries, that); } @Override public <U extends V> TreeMap<K, V> merge(Map<? extends K, U> that, BiFunction<? super V, ? super U, ? extends V> 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<K, V> orElse(Iterable<? extends Tuple2<K, V>> 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<K, V> orElse(Supplier<? extends Iterable<? extends Tuple2<K, V>>> supplier) { return isEmpty() ? ofEntries(comparator(), supplier.get()) : this; } @Override public Tuple2<TreeMap<K, V>, TreeMap<K, V>> partition(Predicate<? super Tuple2<K, V>> predicate) { return Maps.partition(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> peek(Consumer<? super Tuple2<K, V>> action) { return Maps.peek(this, action); } @Override public <U extends V> TreeMap<K, V> put(K key, U value, BiFunction<? super V, ? super U, ? extends V> merge) { return Maps.put(this, key, value, merge); } @Override public TreeMap<K, V> put(K key, V value) { return new TreeMap<>(entries.insert(new Tuple2<>(key, value))); } @Override public TreeMap<K, V> put(Tuple2<? extends K, ? extends V> entry) { return Maps.put(this, entry); } @Override public <U extends V> TreeMap<K, V> put(Tuple2<? extends K, U> entry, BiFunction<? super V, ? super U, ? extends V> merge) { return Maps.put(this, entry, merge); } @Override public TreeMap<K, V> remove(K key) { final V ignored = null; final Tuple2<K, V> entry = new Tuple2<>(key, ignored); if (entries.contains(entry)) { return new TreeMap<>(entries.delete(entry)); } else { return this; } } @Override public TreeMap<K, V> removeAll(BiPredicate<? super K, ? super V> predicate) { return Maps.removeAll(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> removeAll(Iterable<? extends K> keys) { final V ignored = null; RedBlackTree<Tuple2<K, V>> removed = entries; for (K key : keys) { final Tuple2<K, V> 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 public TreeMap<K, V> removeKeys(Predicate<? super K> predicate) { return Maps.removeKeys(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> removeValues(Predicate<? super V> predicate) { return Maps.removeValues(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> replace(Tuple2<K, V> currentElement, Tuple2<K, V> newElement) { return Maps.replace(this, currentElement, newElement); } @Override public TreeMap<K, V> replaceAll(Tuple2<K, V> currentElement, Tuple2<K, V> newElement) { return Maps.replaceAll(this, currentElement, newElement); } @Override public TreeMap<K, V> replaceValue(K key, V value) { return Maps.replaceValue(this, key, value); } @Override public TreeMap<K, V> replace(K key, V oldValue, V newValue) { return Maps.replace(this, key, oldValue, newValue); } @Override public TreeMap<K, V> replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { return Maps.replaceAll(this, function); } @Override public TreeMap<K, V> retainAll(Iterable<? extends Tuple2<K, V>> elements) { Objects.requireNonNull(elements, "elements is null"); RedBlackTree<Tuple2<K, V>> tree = RedBlackTree.empty(entries.comparator()); for (Tuple2<K, V> entry : elements) { if (contains(entry)) { tree = tree.insert(entry); } } return new TreeMap<>(tree); } @Override public TreeMap<K, V> scan( Tuple2<K, V> zero, BiFunction<? super Tuple2<K, V>, ? super Tuple2<K, V>, ? extends Tuple2<K, V>> operation) { return Maps.scan(this, zero, operation, this::createFromEntries); } @Override public int size() { return entries.size(); } @Override public Iterator<TreeMap<K, V>> slideBy(Function<? super Tuple2<K, V>, ?> classifier) { return Maps.slideBy(this, this::createFromEntries, classifier); } @Override public Iterator<TreeMap<K, V>> sliding(int size) { return Maps.sliding(this, this::createFromEntries, size); } @Override public Iterator<TreeMap<K, V>> sliding(int size, int step) { return Maps.sliding(this, this::createFromEntries, size, step); } @Override public Tuple2<TreeMap<K, V>, TreeMap<K, V>> span(Predicate<? super Tuple2<K, V>> predicate) { return Maps.span(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> tail() { if (isEmpty()) { throw new UnsupportedOperationException("tail of empty TreeMap"); } else { final Tuple2<K, V> min = entries.min().get(); return new TreeMap<>(entries.delete(min)); } } @Override public Option<TreeMap<K, V>> tailOption() { return Maps.tailOption(this); } @Override public TreeMap<K, V> take(int n) { return Maps.take(this, this::createFromEntries, n); } @Override public TreeMap<K, V> takeRight(int n) { return Maps.takeRight(this, this::createFromEntries, n); } @Override public TreeMap<K, V> takeUntil(Predicate<? super Tuple2<K, V>> predicate) { return Maps.takeUntil(this, this::createFromEntries, predicate); } @Override public TreeMap<K, V> takeWhile(Predicate<? super Tuple2<K, V>> predicate) { return Maps.takeWhile(this, this::createFromEntries, predicate); } @Override public java.util.TreeMap<K, V> toJavaMap() { return toJavaMap(() -> new java.util.TreeMap<>(comparator()), t -> t); } @Override public Seq<V> values() { return iterator().map(Tuple2::_2).toStream(); } // -- 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 <K, K2, V, V2> TreeMap<K2, V2> bimap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, Function<? super K, ? extends K2> keyMapper, Function<? super V, ? extends V2> 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 <K, V, K2, V2> TreeMap<K2, V2> flatMap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, BiFunction<? super K, ? super V, ? extends Iterable<Tuple2<K2, V2>>> mapper) { Objects.requireNonNull(mapper, "mapper is null"); return createTreeMap(entryComparator, map.entries.iterator().flatMap(entry -> mapper.apply(entry._1, entry._2))); } private static <K, K2, V, V2> TreeMap<K2, V2> map(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, BiFunction<? super K, ? super V, Tuple2<K2, V2>> mapper) { Objects.requireNonNull(mapper, "mapper is null"); return createTreeMap(entryComparator, map.entries, entry -> entry.map(mapper)); } // -- internal factory methods private static <K, V> Collector<Tuple2<K, V>, ArrayList<Tuple2<K, V>>, TreeMap<K, V>> createCollector(EntryComparator<K, V> entryComparator) { final Supplier<ArrayList<Tuple2<K, V>>> supplier = ArrayList::new; final BiConsumer<ArrayList<Tuple2<K, V>>, Tuple2<K, V>> accumulator = ArrayList::add; final BinaryOperator<ArrayList<Tuple2<K, V>>> combiner = (left, right) -> { left.addAll(right); return left; }; final Function<ArrayList<Tuple2<K, V>>, TreeMap<K, V>> finisher = list -> createTreeMap(entryComparator, list); return Collector.of(supplier, accumulator, combiner, finisher); } @SuppressWarnings("unchecked") private static <K, V> TreeMap<K, V> createTreeMap(EntryComparator<K, V> entryComparator, Iterable<? extends Tuple2<? extends K, ? extends V>> entries) { Objects.requireNonNull(entries, "entries is null"); RedBlackTree<Tuple2<K, V>> tree = RedBlackTree.empty(entryComparator); for (Tuple2<K, V> entry : (Iterable<Tuple2<K, V>>) entries) { tree = tree.insert(entry); } return new TreeMap<>(tree); } private static <K, K2, V, V2> TreeMap<K2, V2> createTreeMap(EntryComparator<K2, V2> entryComparator, Iterable<Tuple2<K, V>> entries, Function<Tuple2<K, V>, Tuple2<K2, V2>> entryMapper) { RedBlackTree<Tuple2<K2, V2>> tree = RedBlackTree.empty(entryComparator); for (Tuple2<K, V> entry : entries) { tree = tree.insert(entryMapper.apply(entry)); } return new TreeMap<>(tree); } @SuppressWarnings("unchecked") private static <K, V> TreeMap<K, V> createFromMap(EntryComparator<K, V> entryComparator, java.util.Map<? extends K, ? extends V> map) { Objects.requireNonNull(map, "map is null"); RedBlackTree<Tuple2<K, V>> tree = RedBlackTree.empty(entryComparator); for (java.util.Map.Entry<K, V> entry : ((java.util.Map<K, V>) map).entrySet()) { tree = tree.insert(Tuple.of(entry.getKey(), entry.getValue())); } return new TreeMap<>(tree); } @SuppressWarnings("unchecked") private static <K, V> TreeMap<K, V> createFromTuple(EntryComparator<K, V> entryComparator, Tuple2<? extends K, ? extends V> entry) { Objects.requireNonNull(entry, "entry is null"); return new TreeMap<>(RedBlackTree.of(entryComparator, (Tuple2<K, V>) entry)); } @SuppressWarnings("unchecked") private static <K, V> TreeMap<K, V> createFromTuples(EntryComparator<K, V> entryComparator, Tuple2<? extends K, ? extends V>... entries) { Objects.requireNonNull(entries, "entries is null"); RedBlackTree<Tuple2<K, V>> tree = RedBlackTree.empty(entryComparator); for (Tuple2<? extends K, ? extends V> entry : entries) { tree = tree.insert((Tuple2<K, V>) entry); } return new TreeMap<>(tree); } @SafeVarargs private static <K, V> TreeMap<K, V> createFromMapEntries(EntryComparator<K, V> entryComparator, java.util.Map.Entry<? extends K, ? extends V>... entries) { Objects.requireNonNull(entries, "entries is null"); RedBlackTree<Tuple2<K, V>> tree = RedBlackTree.empty(entryComparator); for (java.util.Map.Entry<? extends K, ? extends V> 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 <K, V> TreeMap<K, V> createFromPairs(EntryComparator<K, V> entryComparator, Object... pairs) { RedBlackTree<Tuple2<K, V>> 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<K, V> createFromEntries(Iterable<Tuple2<K, V>> tuples) { return createTreeMap((EntryComparator<K, V>) entries.comparator(), tuples); } private TreeMap<K, V> emptyInstance() { return isEmpty() ? this : new TreeMap<>(entries.emptyInstance()); } @Override public Comparator<K> comparator() { return ((EntryComparator<K, V>) entries.comparator()).keyComparator(); } // -- internal types private interface EntryComparator<K, V> extends Comparator<Tuple2<K, V>>, Serializable { long serialVersionUID = 1L; static <K, V> EntryComparator<K, V> of(Comparator<? super K> keyComparator) { Objects.requireNonNull(keyComparator, "keyComparator is null"); return new Specific<>(keyComparator); } static <K, V> EntryComparator<K, V> natural() { return Natural.instance(); } Comparator<K> keyComparator(); // -- internal impls final class Specific<K, V> implements EntryComparator<K, V> { private static final long serialVersionUID = 1L; private final Comparator<K> keyComparator; @SuppressWarnings("unchecked") Specific(Comparator<? super K> keyComparator) { this.keyComparator = (Comparator<K>) keyComparator; } @Override public int compare(Tuple2<K, V> e1, Tuple2<K, V> e2) { return keyComparator.compare(e1._1, e2._1); } @Override public Comparator<K> keyComparator() { return keyComparator; } } final class Natural<K, V> implements EntryComparator<K, V> { private static final long serialVersionUID = 1L; private static final Natural<?, ?> INSTANCE = new Natural<>(); // hidden private Natural() { } @SuppressWarnings("unchecked") public static <K, V> Natural<K, V> instance() { return (Natural<K, V>) INSTANCE; } @SuppressWarnings("unchecked") @Override public int compare(Tuple2<K, V> e1, Tuple2<K, V> e2) { final K key1 = e1._1; final K key2 = e2._1; return ((Comparable<K>) key1).compareTo(key2); } @Override public Comparator<K> keyComparator() { return Comparators.naturalComparator(); } /** * Instance control for object serialization. * * @return The singleton instance of NaturalEntryComparator. * @see java.io.Serializable */ private Object readResolve() { return INSTANCE; } } } }