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

net.minestom.server.utils.collection.MergedMap Maven / Gradle / Ivy

There is a newer version: 7320437640
Show newest version
package net.minestom.server.utils.collection;

import org.jetbrains.annotations.ApiStatus;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.stream.Stream;

@ApiStatus.Internal
public final class MergedMap extends AbstractMap {
    private final Map first, second;

    public MergedMap(Map first, Map second) {
        this.first = Objects.requireNonNull(first);
        this.second = Objects.requireNonNull(second);
    }

    // mandatory methods

    final Set> entrySet = new AbstractSet<>() {
        @Override
        public Iterator> iterator() {
            return stream().iterator();
        }

        @Override
        public int size() {
            return (int) stream().count();
        }

        @Override
        public Stream> stream() {
            return Stream.concat(first.entrySet().stream(), secondStream())
                    .map(e -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(), e.getValue()));
        }

        @Override
        public Stream> parallelStream() {
            return stream().parallel();
        }

        @Override
        public Spliterator> spliterator() {
            return stream().spliterator();
        }
    };

    Stream> secondStream() {
        return second.entrySet().stream().filter(e -> !first.containsKey(e.getKey()));
    }

    @Override
    public Set> entrySet() {
        return entrySet;
    }

    // optimizations

    @Override
    public boolean containsKey(Object key) {
        return first.containsKey(key) || second.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        return first.containsValue(value) ||
                secondStream().anyMatch(Predicate.isEqual(value));
    }

    @Override
    public V get(Object key) {
        V v = first.get(key);
        return v != null ? v : second.get(key);
    }

    @Override
    public V getOrDefault(Object key, V defaultValue) {
        V v = first.get(key);
        return v != null ? v : second.getOrDefault(key, defaultValue);
    }

    @Override
    public void forEach(BiConsumer action) {
        first.forEach(action);
        second.forEach((k, v) -> {
            if (!first.containsKey(k)) action.accept(k, v);
        });
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy