com.shapesecurity.functional.data.MultiHashTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of shape-functional-java Show documentation
Show all versions of shape-functional-java Show documentation
Functional programming library
package com.shapesecurity.functional.data;
import com.shapesecurity.functional.F;
import com.shapesecurity.functional.F2;
import com.shapesecurity.functional.Pair;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nonnull;
// Map from keys to multiple values.
// This class does not distinguish between "key is present, but associated with empty list" and "key is not present". If you need that, don't use this class.
@CheckReturnValue
public class MultiHashTable { // TODO should be elsewhere... and better
@Nonnull
private final HashTable> data;
private MultiHashTable(@Nonnull HashTable> data) {
this.data = data;
}
@Nonnull
public static MultiHashTable emptyUsingEquality() {
return new MultiHashTable<>(HashTable.emptyUsingEquality());
}
@Nonnull
public static MultiHashTable emptyUsingIdentity() {
return new MultiHashTable<>(HashTable.emptyUsingIdentity());
}
@Nonnull
@Deprecated
public static MultiHashTable empty() {
return MultiHashTable.emptyUsingEquality();
}
@Nonnull
@Deprecated
public static MultiHashTable emptyP() {
return MultiHashTable.emptyUsingIdentity();
}
@Nonnull
public MultiHashTable put(@Nonnull K key, @Nonnull V value) {
return new MultiHashTable<>(this.data.put(key, ImmutableList.cons(value, this.data.get(key).orJust(ImmutableList.empty()))));
}
@Nonnull
public MultiHashTable remove(@Nonnull K key) {
return new MultiHashTable<>(this.data.remove(key));
}
@Nonnull
public ImmutableList get(@Nonnull K key) {
return this.data.get(key).orJust(ImmutableList.empty());
}
@Nonnull
public MultiHashTable merge(@Nonnull MultiHashTable tree) { // default merge strategy: append lists.
return this.merge(tree, ImmutableList::append);
}
@Nonnull
public MultiHashTable merge(@Nonnull MultiHashTable tree, @Nonnull F2, ImmutableList, ImmutableList> merger) {
return new MultiHashTable<>(this.data.merge(tree.data, merger));
}
@Nonnull
public ImmutableList>> entries() {
return this.data.entries();
}
// version: key is irrelevant
@Nonnull
public HashTable toHashTable(@Nonnull F, B> conversion) {
//return this.data.foldLeft((acc, p) -> acc.put(p.a, conversion.apply(p.b)), HashTable.empty(this.data.hasher));
return this.toHashTable((k, vs) -> conversion.apply(vs));
}
// version: key is used
@Nonnull
public HashTable toHashTable(@Nonnull F2, B> conversion) {
return this.data.foldLeft((acc, p) -> acc.put(p.left, conversion.apply(p.left, p.right)), HashTable.empty(this.data.hasher));
}
@Nonnull
public final ImmutableList> values() {
return this.data.foldLeft((acc, p) -> acc.cons(p.right), ImmutableList.empty());
}
@Nonnull
public final ImmutableList gatherValues() {
return this.data.foldLeft((acc, p) -> acc.append(p.right), ImmutableList.empty());
}
@Nonnull
public final MultiHashTable mapValues(@Nonnull F f) {
return new MultiHashTable<>(this.data.map(l -> l.map(f)));
}
}