VCollections.src.org.violetlib.collections.impl.MappedMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vcollections Show documentation
Show all versions of vcollections Show documentation
Java Immutable Collections
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);
}
}