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

VCollections.src.org.violetlib.collections.impl.MappedMap Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2023 Alan Snyder.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the license agreement. For details see
 * accompanying license terms.
 */

package org.violetlib.collections.impl;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

import org.violetlib.collections.Binding;
import org.violetlib.collections.IIterator;
import org.violetlib.collections.IMap;
import org.violetlib.collections.ISet;
import org.violetlib.collections.SetBuilder;
import org.violetlib.util.Extensions;

import org.jetbrains.annotations.*;
import org.violetlib.annotations.Immutable;

/**
  A virtual map defined using a base map and function that maps base map values to the values of this virtual map.
*/

public final @Immutable class MappedMap
  implements IMap
{
    public static  @NotNull IMap create(@NotNull IMap base, @NotNull Function mapper)
    {
        return new MappedMap<>(base, mapper);
    }

    private final @NotNull IMap base;
    private final @NotNull Function mapper;

    private MappedMap(@NotNull IMap base, @NotNull Function mapper)
    {
        this.base = base;
        this.mapper = mapper;
    }

    @Override
    public @NotNull IIterator> iterator()
    {
        return IMapBindingIterator.create(this);
    }

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

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

    @Override
    public @Nullable V get(@NotNull K key)
    {
        E e = base.get(key);
        return e != null ? mapper.apply(e) : null;
    }

    @Override
    public boolean containsKey(@NotNull Object key)
    {
        try {
            K k = (K) key;
            E e = base.get(k);
            return e != null ? mapper.apply(e) != null : false;
        } catch (ClassCastException ex) {
            // probably of no use in current Java
            return false;
        }
    }

    @Override
    public void visit(@NotNull Visitor visitor)
    {
        base.visit((key, e) -> visitor.visit(key, mapper.apply(e)));
    }

    @Override
    public  @Nullable R find(@NotNull FVisitor visitor, @Nullable R defaultResult)
    {
        return base.find((key, e) -> visitor.visit(key, mapper.apply(e)), defaultResult);
    }

    @Override
    public @NotNull ISet keySet()
    {
        Set result = new HashSet<>();
        for (K key : base.keySet()) {
            V value = get(key);
            if (value != null) {
                result.add(key);
            }
        }
        return SimpleSet.fromSet(result);
    }

    @Override
    public @NotNull ISet values()
    {
        SetBuilder b = ISet.builder();
        for (K key : base.keySet()) {
            V value = get(key);
            if (value != null) {
                b.add(value);
            }
        }
        return b.values();
    }

    @Override
    public @NotNull IMap extending(@NotNull K key, @Nullable V value)
    {
        Map bindings = new HashMap<>();
        visit(bindings::put);
        bindings.put(key, value);
        return Impl.createMap(bindings);
    }

    @Override
    public @NotNull IMap extending(@NotNull IMap delta)
    {
        Map bindings = new HashMap<>();
        visit(bindings::put);
        delta.visit(bindings::put);
        return Impl.createMap(bindings);
    }

    @Override
    public int hashCode()
    {
        return MapEquality.computeHashCode(this);
    }

    @Override
    public boolean equals(@Nullable Object obj)
    {
        if (obj == null) {
            return false;
        }

        if (obj == this) {
            return true;
        }

        IMap otherMap = Extensions.getExtension(obj, IMap.class);
        if (otherMap == null) {
            return false;
        }

        return MapEquality.isEqual(this, otherMap);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy