簡體   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