lundi 15 mars 2021

Comparison of two objects without oids at all levels

I have such objcects:

import lombok.Builder;
import lombok.Data;

import java.util.List;

@Data
@Builder
public class Grandfather {
    private Integer oid;
    private String name;
    private List<Father> childs;
}

@Data
@Builder
public class Father {
    private Integer oid;
    private String name;
    private List<Son> childs;
}

@Data
@Builder
public class Son {
    private Integer oid;
    private String name;
}

I would like to compare two objects which are type of Grandfather by recursion method, that use also reflection. That method compare all fields of object at all level without field oid. Below I present the objects that should be treated as the same when compared:

Son son1 = Son.builder()
                .oid(100)
                .name("Paul")
                .build();
        Son son2 = Son.builder()
                .oid(null)
                .name("Paul")
                .build();
        Father father1 = Father.builder()
                .oid(32)
                .name("Alex")
                .childs(Collections.singletonList(son1))
                .build();
        Father father2 = Father.builder()
                .oid(567)
                .name("Alex")
                .childs(Collections.singletonList(son2))
                .build();
        Grandfather grandfather1 = Grandfather.builder()
                .oid(12)
                .name("John")
                .childs(Collections.singletonList(father1))
                .build();
        Grandfather grandfather2 = Grandfather.builder()
                .oid(1222)
                .name("John")
                .childs(Collections.singletonList(father2))
                .build();

I wrote this method but unfortunately it does not work. This method uses reflection through which it iterates through the objects (fields) of a given object. Unfortunately, it uses recursions badly.

public static boolean haveSameValuesExceptOneField(Class<?> type, Object t1, Object t2, String exceptGetter)
            throws Exception {
        for (Method m : type.getMethods()) {
            if (!m.getName().equals(exceptGetter) && isGetter(m)) {
                final Object o1 = m.invoke(t1);
                final Object o2 = m.invoke(t2);
                if (!Objects.equals(o1, o2)) {
                    return haveSameValuesExceptOneField(m.invoke(t2).getClass(), m.invoke(t1), m.invoke(t2), exceptGetter);
                }
            }
        }
        return true;
    }

private static boolean isGetter(Method method) {
        return method.getName().startsWith("get") && method.getParameterTypes().length == 0;
    }

This is how I call this method:

System.out.println(haveSameValuesExceptOneField(Grandfather.class, grandfather1, grandfather2, "getOid"));

How can I fix this method to make it work the way I want?





Aucun commentaire:

Enregistrer un commentaire