package com.jediq.hashcodeequals;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 *
 */
public class LambdaEqualsHashCode<T> {

    private static final int SEED = 31;

    private Class<T> clazz;

    private List<Function<T, Object> > attributes = new ArrayList<>();

    public LambdaEqualsHashCode(Class<T> clazz) {
        this.clazz = clazz;
    }

    public LambdaEqualsHashCode<T> with(Function<T, Object> attribute) {
        attributes.add(attribute);
        return this;
    }

    public boolean areEqual(T left, Object right) {
        if (left == right) {
            return true;
        }
        if (!clazz.isInstance(left) || !clazz.isInstance(right)) {
            return false;
        }
        for (Function<T, Object>  attribute : attributes) {
            if (areAttributesDifferent(left, right, attribute)) {
                return false;
            }
        }
        return true;
    }

    private boolean areAttributesDifferent(T left, Object right, Function attribute) {
        Object leftAttribute = attribute.apply(left);
        Object rightAttribute = attribute.apply(right);
        return leftAttribute == null && rightAttribute != null 
                || leftAttribute != null && !leftAttribute.equals(rightAttribute);
    }

    public int hashCodeFor(T object) {
        int value = SEED;
        for (Function<T, Object>  attribute : attributes) {
            Object attributeValue = attribute.apply(object);
            if (attributeValue != null) {
                value += attributeValue.hashCode() * SEED * value;
            }
        }
        return value;
    }
}
@@ -522,32 +522,392 @@
 rn this;%0A    %7D%0A%0A
+    public int hashCodeFor(T object) %7B%0A        int total = SEED;%0A        for (Function%3CT, Object%3E  attribute : attributes) %7B%0A            Object attributeValue = attribute.apply(object);%0A            total *= SEED;%0A            if (attributeValue != null) %7B%0A                total += attributeValue.hashCode();%0A            %7D%0A        %7D%0A        return total;%0A    %7D%0A%0A
     public boole
@@ -1670,354 +1670,6 @@
    %7D
-%0A%0A    public int hashCodeFor(T object) %7B%0A        int value = SEED;%0A        for (Function%3CT, Object%3E  attribute : attributes) %7B%0A            Object attributeValue = attribute.apply(object);%0A            if (attributeValue != null) %7B%0A                value += attributeValue.hashCode() * SEED * value;%0A            %7D%0A        %7D%0A        return value;%0A    %7D
 %0A%7D

tidy up hashCode() modelling agianst apache.commons algorithm