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

com.github.simonharmonicminor.juu.collection.immutable.ImmutableHashMap Maven / Gradle / Ivy

There is a newer version: 1.2
Show newest version
package com.github.simonharmonicminor.juu.collection.immutable;

import com.github.simonharmonicminor.juu.lambda.TriFunction;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.github.simonharmonicminor.juu.collection.immutable.Immutable.listOf;
import static com.github.simonharmonicminor.juu.collection.immutable.Immutable.setOf;
import static com.github.simonharmonicminor.juu.collection.immutable.ImmutableCollectionUtils.mapEquals;

/**
 * An immutable implementation of java native {@link HashMap}
 *
 * @param  the type of the key
 * @param  the type of the value
 * @see ImmutableMap
 * @see HashMap
 * @see Serializable
 * @since 1.0
 */
public class ImmutableHashMap implements ImmutableMap, Serializable {
    private static final TriFunction KEEP_OLD = (key, oldVal, newVal) -> oldVal;
    private static final TriFunction KEEP_NEW = (key, oldVal, newVal) -> newVal;

    private final HashMap hashMap;
    private final ImmutableSet keys;
    private final ImmutableList values;
    private final ImmutableSet> pairs;

    public ImmutableHashMap(Map map) {
        this(map, true);
    }

    ImmutableHashMap(Map map, boolean needsCloning) {
        if (needsCloning || !(map instanceof HashMap)) this.hashMap = new HashMap<>(map);
        else this.hashMap = (HashMap) map;
        this.keys = setOf(hashMap.keySet());
        this.values = listOf(hashMap.values());
        this.pairs =
                setOf(hashMap.entrySet().stream()
                        .map(e -> Pair.of(e.getKey(), e.getValue()))
                        .collect(Collectors.toList()));
    }

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

    @Override
    public boolean isEmpty() {
        return hashMap.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return hashMap.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        return hashMap.containsValue(value);
    }

    private static  ImmutableMap concatenation(
            ImmutableMap immutableMap,
            HashMap oldHashMap,
            TriFunction overrideBehaviour) {
        HashMap newHashMap = new HashMap<>(oldHashMap);
        immutableMap.forEach(
                (k, v) -> {
                    if (oldHashMap.containsKey(k)) {
                        newHashMap.put(k, overrideBehaviour.apply(k, oldHashMap.get(k), v));
                    } else {
                        newHashMap.put(k, v);
                    }
                });
        return new ImmutableHashMap<>(newHashMap, false);
    }

    @Override
    @SuppressWarnings("unchecked")
    public ImmutableMap concatWithOverride(ImmutableMap map) {
        Objects.requireNonNull(map);
        return concatenation(map, this.hashMap, (TriFunction) KEEP_NEW);
    }

    @Override
    @SuppressWarnings("unchecked")
    public ImmutableMap concatWithoutOverride(ImmutableMap map) {
        Objects.requireNonNull(map);
        return concatenation(map, this.hashMap, (TriFunction) KEEP_OLD);
    }

    @Override
    public ImmutableMap concatWith(
            ImmutableMap map, TriFunction overrideBehaviour) {
        Objects.requireNonNull(map);
        Objects.requireNonNull(overrideBehaviour);
        return concatenation(map, this.hashMap, overrideBehaviour);
    }

    @Override
    public V get(Object key) {
        return hashMap.get(key);
    }

    @Override
    public ImmutableSet keySet() {
        return keys;
    }

    @Override
    public ImmutableList values() {
        return values;
    }

    @Override
    public ImmutableSet> pairSet() {
        return pairs;
    }

    @Override
    public Map toMutableMap() {
        return new HashMap<>(hashMap);
    }

    @Override
    public boolean equals(Object o) {
        return mapEquals(this, o);
    }

    @Override
    public int hashCode() {
        return Objects.hash(hashMap);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy