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 org.jetbrains.annotations.NotNull;
// 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.
public class MultiHashTable { // TODO should be elsewhere... and better
@NotNull
private final HashTable> data;
private MultiHashTable(@NotNull HashTable> data) {
this.data = data;
}
@NotNull
public static MultiHashTable empty() { // uses equality (.equals)
return new MultiHashTable<>(HashTable.empty());
}
@NotNull
public static MultiHashTable emptyP() { // uses identity (==)
return new MultiHashTable<>(HashTable.emptyP());
}
@NotNull
public MultiHashTable put(@NotNull K key, @NotNull V value) {
return new MultiHashTable<>(this.data.put(key, ImmutableList.cons(value, this.data.get(key).orJust(ImmutableList.nil()))));
}
@NotNull
public MultiHashTable remove(@NotNull K key) {
return new MultiHashTable<>(this.data.remove(key));
}
@NotNull
public ImmutableList get(@NotNull K key) {
return this.data.get(key).orJust(ImmutableList.nil());
}
@NotNull
public MultiHashTable merge(@NotNull MultiHashTable tree) { // default merge strategy: append lists.
return this.merge(tree, ImmutableList::append);
}
@NotNull
public MultiHashTable merge(@NotNull MultiHashTable tree, @NotNull F2, ImmutableList, ImmutableList> merger) {
return new MultiHashTable<>(this.data.merge(tree.data, merger));
}
@NotNull
public ImmutableList>> entries() {
return this.data.entries();
}
// version: key is irrelevant
@NotNull
public HashTable toHashTable(@NotNull 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
@NotNull
public HashTable toHashTable(@NotNull F2, B> conversion) {
return this.data.foldLeft((acc, p) -> acc.put(p.a, conversion.apply(p.a, p.b)), HashTable.empty(this.data.hasher));
}
@NotNull
public final ImmutableList> values() {
return this.data.foldLeft((acc, p) -> acc.cons(p.b), ImmutableList.nil());
}
@NotNull
public final ImmutableList gatherValues() {
return this.data.foldLeft((acc, p) -> acc.append(p.b), ImmutableList.nil());
}
@NotNull
public final MultiHashTable mapValues(@NotNull F f) {
return new MultiHashTable<>(this.data.map(l -> l.map(f::apply)));
}
}