fj.data.HashMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of functionaljava Show documentation
Show all versions of functionaljava Show documentation
Functional Java is an open source library that supports closures for the Java programming language
package fj.data;
import fj.*;
import fj.function.Effect1;
import java.util.Collection;
import java.util.Iterator;
import static fj.P.p;
import static fj.data.Option.fromNull;
/**
* A mutable hash map providing O(1) lookup.
*
* @version %build.number%
* @see java.util.HashMap
*/
public final class HashMap implements Iterable {
private final class Key {
private final K k;
private final Equal e;
private final Hash h;
Key(final K k, final Equal e, final Hash h) {
this.k = k;
this.e = e;
this.h = h;
}
K k() {
return k;
}
@SuppressWarnings({"unchecked"})
public boolean equals(final Object o) {
return o instanceof Key && e.eq(k, (K) ((Key>) o).k());
}
public int hashCode() {
return h.hash(k);
}
}
/**
* Returns an iterator for this map's keys. This method exists to permit the use in a for
-each loop.
*
* @return A iterator for this map's keys.
*/
public Iterator iterator() {
return keys().iterator();
}
private final java.util.HashMap, V> m;
private final Equal e;
private final Hash h;
/**
* Construct a hash map with the given equality and hashing strategy.
*
* @param e The equality strategy.
* @param h The hashing strategy.
*/
public HashMap(final Equal e, final Hash h) {
m = new java.util.HashMap, V>();
this.e = e;
this.h = h;
}
public HashMap(java.util.Map map, final Equal e, final Hash h) {
this(e, h);
for (K key : map.keySet()) {
set(key, map.get(key));
}
}
/**
* Construct a hash map with the given equality and hashing strategy.
*
* @param e The equality strategy.
* @param h The hashing strategy.
* @param initialCapacity The initial capacity.
*/
public HashMap(final Equal e, final Hash h, final int initialCapacity) {
m = new java.util.HashMap, V>(initialCapacity);
this.e = e;
this.h = h;
}
public HashMap(java.util.Map map) {
this(map, Equal.anyEqual(), Hash.anyHash());
}
/**
* Construct a hash map with the given equality and hashing strategy.
*
* @param e The equality strategy.
* @param h The hashing strategy.
* @param initialCapacity The initial capacity.
* @param loadFactor The load factor.
*/
public HashMap(final Equal e, final Hash h, final int initialCapacity, final float loadFactor) {
m = new java.util.HashMap, V>(initialCapacity, loadFactor);
this.e = e;
this.h = h;
}
/**
* Construct a hash map that uses {@link Object#equals} and {@link Object#hashCode}.
*
* @return A new hash map that uses {@link Object#equals} and {@link Object#hashCode}.
*/
public static HashMap hashMap() {
final Equal e = Equal.anyEqual();
final Hash h = Hash.anyHash();
return new HashMap(e, h);
}
/**
* Compare two key values for equality using the underlying equality strategy.
*
* @param k1 One key value to compare.
* @param k2 The other key value to compare.
* @return true
if the two key values are equal, false
otherwise.
*/
public boolean eq(final K k1, final K k2) {
return e.eq(k1, k2);
}
/**
* Compute the hash of the given key value using the underlying hashing strategy.
*
* @param k The key value to computer the hash of.
* @return The hash of the given key value.
*/
public int hash(final K k) {
return h.hash(k);
}
/**
* Returns a potential value that the given key maps to.
*
* @param k The key to look up in the hash map.
* @return A potential value for the given key.
*/
public Option get(final K k) {
return fromNull(m.get(new Key(k, e, h)));
}
/**
* A curried version of {@link #get(Object)}.
*
* @return A curried version of {@link #get(Object)}.
*/
public F> get() {
return new F>() {
public Option f(final K k) {
return get(k);
}
};
}
/**
* Clear all entries from this hash map.
*/
public void clear() {
m.clear();
}
/**
* Determines if the given key value exists in this hash map.
*
* @param k The key value to look for in this hash map.
* @return true
if this hash map contains the given key, false
otherwise.
*/
public boolean contains(final K k) {
return m.containsKey(new Key(k, e, h));
}
/**
* Returns all key entries in this hash map.
*
* @return All key entries in this hash map.
*/
public List keys() {
final List.Buffer b = new List.Buffer();
for (final Key k : m.keySet()) {
b.snoc(k.k());
}
return b.toList();
}
/**
* Returns all values in this hash map.
*
* @return All values in this hash map.
*/
public List values() {
return keys().map(new F() {
public V f(final K k) {
return m.get(new Key(k, e, h));
}
});
}
/**
* Determines if this hash map has any entries.
*
* @return true
if this hash map has no entries, false
otherwise.
*/
public boolean isEmpty() {
return m.isEmpty();
}
/**
* Returns the number of entries in this hash map.
*
* @return The number of entries in this hash map.
*/
public int size() {
return m.size();
}
/**
* Inserts the given key and value association into the hash map.
*
* @param k The key to insert.
* @param v The value to insert.
*/
public void set(final K k, final V v) {
if (v != null) {
m.put(new Key(k, e, h), v);
}
}
/**
* Deletes the entry in the hash map that corresponds to the given key.
*
* @param k The key to delete from this hash map.
*/
public void delete(final K k) {
m.remove(new Key(k, e, h));
}
/**
* Deletes the entry in the hash map that corresponds to the given key and returns any associated value.
*
* @param k The key to delete from this hash map.
* @return The value that was associated with the given key, if there was one.
*/
public Option getDelete(final K k) {
return fromNull(m.remove(new Key(k, e, h)));
}
public HashMap map(F keyFunction,
F valueFunction,
Equal equal, Hash hash) {
final HashMap hashMap = new HashMap(equal, hash);
for (K key : keys()) {
final A newKey = keyFunction.f(key);
final B newValue = valueFunction.f(get(key).some());
hashMap.set(newKey, newValue);
}
return hashMap;
}
public HashMap map(F keyFunction,
F valueFunction) {
return map(keyFunction, valueFunction, Equal.anyEqual(), Hash.anyHash());
}
public HashMap map(F, P2> function, Equal equal, Hash hash) {
return from(toStream().map(function), equal, hash);
}
public HashMap map(F, P2> function) {
return from(toStream().map(function));
}
public HashMap mapKeys(F keyFunction, Equal equal, Hash hash) {
return map(keyFunction, Function.identity(), equal, hash);
}
public HashMap mapKeys(F function) {
return mapKeys(function, Equal.anyEqual(), Hash.anyHash());
}
public HashMap mapValues(F function) {
return map(Function.identity(), function, e, h);
}
public void foreachDoEffect(Effect1> effect) {
toStream().foreachDoEffect(effect);
}
public void foreach(F, Unit> function) {
toStream().foreach(function);
}
public List> toList() {
return keys().map(k -> p(k, get(k).some()));
}
/**
* Projects an immutable collection of this hash map.
*
* @return An immutable collection of this hash map.
*/
public Collection> toCollection() {
return toList().toCollection();
}
public Stream> toStream() {
return toList().toStream();
}
public Option> toOption() {
return toList().toOption();
}
public Array> toArray() {
return toList().toArray();
}
public java.util.Map toMap() {
final java.util.HashMap result = new java.util.HashMap();
for (K key : keys()) {
result.put(key, get(key).some());
}
return result;
}
public static HashMap from(Iterable> entries) {
return from(entries, Equal.anyEqual(), Hash.anyHash());
}
public static HashMap from(Iterable> entries, Equal equal, Hash hash) {
final HashMap map = new HashMap(equal, hash);
for (P2 entry : entries) {
map.set(entry._1(), entry._2());
}
return map;
}
}