繁体   English   中英

两个没有oid的对象在所有级别的比较

[英]Comparison of two objects without oids at all levels

我有这样的对象:

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;
}

我想通过递归方法比较两个祖父类型的对象,它们也使用反射。 该方法比较 object 的所有字段在所有级别没有字段 oid。 下面我介绍比较时应该被视为相同的对象:

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();

我写了这个方法,但不幸的是它不起作用。 此方法使用反射,通过它迭代给定 object 的对象(字段)。 不幸的是,它糟糕地使用了递归。

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;
    }

这就是我调用此方法的方式:

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

如何修复此方法以使其按我想要的方式工作?

在您的for (Method m: type.getMethods())循环中,您在比较第一对不为Objects.equal的字段后返回。 第一个字段使得t1.getField()不是Objects.equal t2.getField()将停止对象 t1 和 t2 中其他字段的比较。

if (!Objects.equals(o1, o2) &&
    !haveSameValuesExceptOneField(m.invoke(t2).getClass(), 
                                  m.invoke(t1), 
                                  m.invoke(t2), 
                                  exceptGetter)) {
        return false;
    }
}
// continue the loop - keep comparing other fields

如果你们中的任何人知道如何比较这些对象,不一定使用反射或递归,那么我也在寻求这样的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM