fj.Hash 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;
import static fj.Function.compose;
import fj.data.*;
import fj.data.vector.V2;
import fj.data.vector.V3;
import fj.data.vector.V4;
import fj.data.vector.V5;
import fj.data.vector.V6;
import fj.data.vector.V7;
import fj.data.vector.V8;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* Produces a hash code for an object which should attempt uniqueness.
*
* @version %build.number%
*/
public final class Hash {
private final F f;
private Hash(final F f) {
this.f = f;
}
/**
* Compute the hash of the given value.
*
* @param a The value to compute the hash value for.
* @return The hash value.
*/
public int hash(final A a) {
return f.f(a);
}
/**
* Maps the given function across this hash as a contra-variant functor.
*
* @param g The function to map.
* @return A new hash.
*/
public Hash contramap(final F g) {
return hash(compose(f, g));
}
/**
* Construct a hash with the given hash function.
*
* @param f The function to construct the hash with.
* @return A hash that uses the given function.
*/
public static Hash hash(final F f) {
return new Hash<>(f);
}
/**
* A hash that uses {@link Object#hashCode()}.
*
* @return A hash that uses {@link Object#hashCode()}.
*/
public static Hash anyHash() {
return hash(Object::hashCode);
}
/**
* A hash instance for the boolean
type.
*/
public static final Hash booleanHash = anyHash();
/**
* A hash instance for the byte
type.
*/
public static final Hash byteHash = anyHash();
/**
* A hash instance for the char
type.
*/
public static final Hash charHash = anyHash();
/**
* A hash instance for the double
type.
*/
public static final Hash doubleHash = anyHash();
/**
* A hash instance for the float
type.
*/
public static final Hash floatHash = anyHash();
/**
* A hash instance for the int
type.
*/
public static final Hash intHash = anyHash();
/**
* A hash instance for the long
type.
*/
public static final Hash longHash = anyHash();
/**
* A hash instance for the short
type.
*/
public static final Hash shortHash = anyHash();
/**
* A hash instance for the BigInteger
type.
*/
public static final Hash bigintHash = anyHash();
/**
* A hash instance for the BigDecimal
type.
*/
public static final Hash bigdecimalHash = anyHash();
/**
* A hash instance for the {@link Natural} type.
*/
public static final Hash naturalHash = bigintHash.contramap(Natural::bigIntegerValue);
/**
* A hash instance for the String
type.
*/
public static final Hash stringHash = anyHash();
/**
* A hash instance for the {@link StringBuffer} type.
*/
public static final Hash stringBufferHash = hash(sb -> {
final int p = 419;
int r = 239;
for (int i = 0; i < sb.length(); i++)
r = p * r + sb.charAt(i);
return r;
});
/**
* A hash instance for the {@link StringBuilder} type.
*/
public static final Hash stringBuilderHash = hash(sb -> {
final int p = 419;
int r = 239;
for (int i = 0; i < sb.length(); i++)
r = p * r + sb.charAt(i);
return r;
});
/**
* A hash instance for the {@link Either} type.
*
* @param ha Hash the left side of Either
.
* @param hb Hash the right side of Either
.
* @return A hash instance for the {@link Either} type.
*/
public static Hash> eitherHash(final Hash ha, final Hash hb) {
return hash(e -> e.isLeft() ? ha.hash(e.left().value()) : hb.hash(e.right().value()));
}
/**
* A hash instance for the {@link Validation} type.
*
* @param ha Hash the failing side of Validation
.
* @param hb Hash the succeeding side of Validation
.
* @return A hash instance for the {@link Validation} type.
*/
public static Hash> validationHash(final Hash ha, final Hash hb) {
return eitherHash(ha, hb).contramap(Validation.either());
}
/**
* A hash instance for the {@link List} type.
*
* @param ha A hash for the elements of the list.
* @return A hash instance for the {@link List} type.
*/
public static Hash> listHash(final Hash ha) {
return hash(as -> {
final int p = 419;
int r = 239;
List aas = as;
while (!aas.isEmpty()) {
r = p * r + ha.hash(aas.head());
aas = aas.tail();
}
return r;
});
}
/**
* A hash instance for the {@link NonEmptyList} type.
*
* @param ha A hash for the elements of the non-empty list.
* @return A hash instance for the {@link NonEmptyList} type.
*/
public static Hash> nonEmptyListHash(final Hash ha) {
return listHash(ha).contramap(NonEmptyList.toList_());
}
/**
* A hash instance for the {@link Option} type.
*
* @param ha A hash for the element of the optional value.
* @return A hash instance for the {@link Option} type.
*/
public static Hash