package com.jediq.hashcodeequals;

import java.util.ArrayList;
import java.util.List;

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

    private static final int SEED = 31;

    private Class<T> clazz;

    private List<Attribute<T>> attributes = new ArrayList<>();

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

    public LambdaEqualsHashCode<T> with(Attribute<T> 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 (Attribute attribute : attributes) {
            if (areAttributesDifferent(left, right, attribute)) {
                return false;
            }
        }
        return true;
    }

    private boolean areAttributesDifferent(T left, Object right, Attribute attribute) {
        Object leftAttribute = attribute.value(left);
        Object rightAttribute = attribute.value(right);
        if (leftAttribute == null && rightAttribute != null) {
            return true;
        }
        if (leftAttribute != null && !leftAttribute.equals(rightAttribute)) {
            return true;
        }
        return false;
    }

    public int hashCodeFor(T object) {
        int value = SEED;
        for (Attribute attribute : attributes) {
            Object attributeValue = attribute.value(object);
            if (attributeValue != null) {
                value += attributeValue.hashCode() * SEED * value;
            }
        }
        return value;
    }

    public interface Attribute<U> {
        Object value(U t);
    }
}
@@ -78,16 +78,52 @@
 il.List;
+%0Aimport java.util.function.Function;
 %0A%0A/**%0A *
@@ -254,28 +254,36 @@
 te List%3C
-Attribute%3CT%3E
+Function%3CT, Object%3E 
 %3E attrib
@@ -438,19 +438,26 @@
 ith(
-Attribute%3CT
+Function%3CT, Object
 %3E at
@@ -758,33 +758,44 @@
        for (
-Attribute
+Function%3CT, Object%3E 
  attribute :
@@ -1022,25 +1022,24 @@
  right, 
-Attribute
+Function
  attribu
@@ -1085,21 +1085,21 @@
 tribute.
-value
+apply
 (left);%0A
@@ -1140,21 +1140,21 @@
 tribute.
-value
+apply
 (right);
@@ -1154,36 +1154,39 @@
 right);%0A        
-if (
+return 
 leftAttribute ==
@@ -1208,35 +1208,33 @@
 ttribute != null
-) %7B
+ 
 %0A            ret
@@ -1234,43 +1234,15 @@
     
-return true;%0A        %7D%0A        if (
+    %7C%7C 
 left
@@ -1303,67 +1303,8 @@
 ute)
-) %7B%0A            return true;%0A        %7D%0A        return false
 ;%0A  
@@ -1386,25 +1386,36 @@
    for (
-Attribute
+Function%3CT, Object%3E 
  attribu
@@ -1479,21 +1479,21 @@
 tribute.
-value
+apply
 (object)
@@ -1658,76 +1658,6 @@
    %7D
-%0A%0A    public interface Attribute%3CU%3E %7B%0A        Object value(U t);%0A    %7D
 %0A%7D

use Function.class rather than custom Attribute class