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

javaslang.collection.Maps Maven / Gradle / Ivy

/*     / \____  _    _  ____   ______  / \ ____  __    _______
 *    /  /    \/ \  / \/    \ /  /\__\/  //    \/  \  //  /\__\   JΛVΛSLΛNG
 *  _/  /  /\  \  \/  /  /\  \\__\\  \  //  /\  \ /\\/ \ /__\ \   Copyright 2014-2016 Javaslang, http://javaslang.io
 * /___/\_/  \_/\____/\_/  \_/\__\/__/\__\_/  \_//  \__/\_____/   Licensed under the Apache License, Version 2.0
 */
package javaslang.collection;

import javaslang.Tuple;
import javaslang.Tuple2;
import javaslang.control.Option;

import java.util.Comparator;
import java.util.Objects;
import java.util.function.*;

/**
 * Implementations of common {@code Map} functions (not intended to be public).
 *
 * @author Ruslan Sennov, Daniel Dietrich
 * @since 2.0.0
 */
final class Maps {

    static > M distinct(M map) {
        return map;
    }

    static > M distinctBy(M map, OfEntries ofEntries,
                                                    Comparator> comparator) {
        Objects.requireNonNull(comparator, "comparator is null");
        return ofEntries.apply(map.iterator().distinctBy(comparator));
    }

    static > M distinctBy(
            M map, OfEntries ofEntries, Function, ? extends U> keyExtractor) {
        Objects.requireNonNull(keyExtractor, "keyExtractor is null");
        return ofEntries.apply(map.iterator().distinctBy(keyExtractor));
    }

    static > M drop(M map, OfEntries ofEntries, Supplier emptySupplier, long n) {
        if (n <= 0) {
            return map;
        } else if (n >= map.size()) {
            return emptySupplier.get();
        } else {
            return ofEntries.apply(map.iterator().drop(n));
        }
    }

    static > M dropRight(M map, OfEntries ofEntries, Supplier emptySupplier,
                                                   long n) {
        if (n <= 0) {
            return map;
        } else if (n >= map.size()) {
            return emptySupplier.get();
        } else {
            return ofEntries.apply(map.iterator().dropRight(n));
        }
    }

    static > M dropUntil(M map, OfEntries ofEntries,
                                                   Predicate> predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return dropWhile(map, ofEntries, predicate.negate());
    }

    static > M dropWhile(M map, OfEntries ofEntries,
                                                   Predicate> predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return ofEntries.apply(map.iterator().dropWhile(predicate));
    }

    static > M filter(M map, OfEntries ofEntries,
                                                BiPredicate predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return filter(map, ofEntries, t -> predicate.test(t._1, t._2));
    }

    static > M filter(M map, OfEntries ofEntries,
                                                Predicate> predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return ofEntries.apply(map.iterator().filter(predicate));
    }

    static > M filterKeys(M map, OfEntries ofEntries,
                                                    Predicate predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return filter(map, ofEntries, t -> predicate.test(t._1));
    }

    static > M filterValues(M map, OfEntries ofEntries,
                                                      Predicate predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return filter(map, ofEntries, t -> predicate.test(t._2));
    }

    static > Map groupBy(M map, OfEntries ofEntries,
                                                            Function, ? extends C> classifier) {
        return Collections.groupBy(map, classifier, ofEntries);
    }

    static > Iterator grouped(M map, OfEntries ofEntries, long size) {
        return sliding(map, ofEntries, size, size);
    }

    @SuppressWarnings("unchecked")
    static > Option initOption(M map) {
        return map.isEmpty() ? Option.none() : Option.some((M) map.init());
    }

    static > M merge(M map, OfEntries ofEntries,
                                               Map that) {
        Objects.requireNonNull(that, "that is null");
        if (map.isEmpty()) {
            return ofEntries.apply(Map.narrow(that));
        } else if (that.isEmpty()) {
            return map;
        } else {
            return that.foldLeft(map, (result, entry) -> !result.containsKey(entry._1) ? put(result, entry) : result);
        }
    }

    @SuppressWarnings("unchecked")
    static > M merge(
            M map, OfEntries ofEntries,
            Map that, BiFunction collisionResolution) {
        Objects.requireNonNull(that, "that is null");
        Objects.requireNonNull(collisionResolution, "collisionResolution is null");
        if (map.isEmpty()) {
            return ofEntries.apply(Map.narrow(that));
        } else if (that.isEmpty()) {
            return map;
        } else {
            return that.foldLeft(map, (result, entry) -> {
                final K key = entry._1;
                final U value = entry._2;
                final V newValue = result.get(key).map(v -> (V) collisionResolution.apply(v, value)).getOrElse(value);
                return (M) result.put(key, newValue);
            });
        }
    }

    static > Tuple2 partition(M map, OfEntries ofEntries,
                                                              Predicate> predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        final Tuple2>, Iterator>> p = map.iterator().partition(predicate);
        return Tuple.of(ofEntries.apply(p._1), ofEntries.apply(p._2));
    }

    static > M peek(M map, Consumer> action) {
        Objects.requireNonNull(action, "action is null");
        if (!map.isEmpty()) {
            action.accept(map.head());
        }
        return map;
    }

    @SuppressWarnings("unchecked")
    static > M put(M map, K key, U value,
                                                          BiFunction merge) {
        Objects.requireNonNull(merge, "the merge function is null");
        final Option currentValue = map.get(key);
        if (currentValue.isEmpty()) {
            return (M) map.put(key, value);
        } else {
            return (M) map.put(key, merge.apply(currentValue.get(), value));
        }
    }

    @SuppressWarnings("unchecked")
    static > M put(M map, Tuple2 entry) {
        Objects.requireNonNull(entry, "entry is null");
        return (M) map.put(entry._1, entry._2);
    }

    static > M put(M map, Tuple2 entry,
                                                          BiFunction merge) {
        Objects.requireNonNull(merge, "the merge function is null");
        final Option currentValue = map.get(entry._1);
        if (currentValue.isEmpty()) {
            return put(map, entry);
        } else {
            return put(map, entry.map2(value -> merge.apply(currentValue.get(), value)));
        }
    }

    static > M removeAll(M map, OfEntries ofEntries,
                                                   BiPredicate predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return filter(map, ofEntries, predicate.negate());
    }

    static > M removeKeys(M map, OfEntries ofEntries,
                                                    Predicate predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return filterKeys(map, ofEntries, predicate.negate());
    }

    static > M removeValues(M map, OfEntries ofEntries,
                                                      Predicate predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return filterValues(map, ofEntries, predicate.negate());
    }

    @SuppressWarnings("unchecked")
    static > M replace(M map, Tuple2 currentElement, Tuple2 newElement) {
        Objects.requireNonNull(currentElement, "currentElement is null");
        Objects.requireNonNull(newElement, "newElement is null");
        return (M) (map.containsKey(currentElement._1) ? map.remove(currentElement._1).put(newElement) : map);
    }

    static > M replaceAll(M map, Tuple2 currentElement, Tuple2 newElement) {
        return replace(map, currentElement, newElement);
    }

    static > M scan(
            M map, Supplier emptySupplier, Tuple2 zero,
            BiFunction, ? super Tuple2, ? extends Tuple2> operation) {
        Objects.requireNonNull(operation, "operation is null");
        return Collections.scanLeft(map, zero, operation, emptySupplier.get(), Maps::put, Function.identity());
    }

    static > Iterator sliding(M map, OfEntries ofEntries, long size) {
        return sliding(map, ofEntries, size, 1);
    }

    static > Iterator sliding(M map, OfEntries ofEntries, long size, long step) {
        return map.iterator().sliding(size, step).map(ofEntries);
    }

    static > Tuple2 span(M map, OfEntries ofEntries,
                                                         Predicate> predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        final Tuple2>, Iterator>> t = map.iterator().span(predicate);
        return Tuple.of(ofEntries.apply(t._1), ofEntries.apply(t._2));
    }

    @SuppressWarnings("unchecked")
    static > Option tailOption(M map) {
        return map.isEmpty() ? Option.none() : Option.some((M) map.tail());
    }

    static > M take(M map, OfEntries ofEntries, long n) {
        if (n >= map.size()) {
            return map;
        } else {
            return ofEntries.apply(map.iterator().take(n));
        }
    }

    static > M takeRight(M map, OfEntries ofEntries, long n) {
        if (n >= map.size()) {
            return map;
        } else {
            return ofEntries.apply(map.iterator().takeRight(n));
        }
    }

    static > M takeUntil(M map, OfEntries ofEntries,
                                                   Predicate> predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        return takeWhile(map, ofEntries, predicate.negate());
    }

    static > M takeWhile(M map, OfEntries ofEntries,
                                                   Predicate> predicate) {
        Objects.requireNonNull(predicate, "predicate is null");
        final M taken = ofEntries.apply(map.iterator().takeWhile(predicate));
        return taken.size() == map.size() ? map : taken;
    }

    @FunctionalInterface
    interface OfEntries> extends Function>, M> {
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy