[英]How would I compare field values of two Java objects of the same but unknown type recursively?
我們正在使用 JAXB 將 XML 配置文件解析為 Java 對象。 XML 文件是版本化的,在將 1.0 和 2.0 版加載到對象中后,我們希望遞歸比較兩個相同但未知類型的對象(各種事物有許多不同的配置)及其字段值並打印出差異.
一個對象可能如下所示。
@XmlRootElement(name = "HelloWorld")
public class HelloWorldConfiguration {
private List<HelloWorldObject> helloWorldObjects = new ArrayList<HelloWorldObject>();
public HelloWorldConfiguration() {
HelloWorldObject o = new HelloWorldObject();
helloWorldObjects.add(o);
helloWorldObjects.add(o);
helloWorldObjects.add(o);
helloWorldObjects.add(o);
helloWorldObjects.add(o);
}
@XmlElement(name = "helloWorldObject")
public List<HelloWorldObject> getHelloWorldObjects() {
return helloWorldObjects;
}
public void setHelloWorldObjects(List<HelloWorldObject> helloWorldObjects) {
this.helloWorldObjects = helloWorldObjects;
}
}
public class HelloWorldObject {
private Stage firstName = new Stage("Tony");
private Stage secondName = new Stage("Stark");
public Stage getFirstName() {
return firstName;
}
public void setFirstName(Stage firstName) {
this.firstName = firstName;
}
public Stage getSecondName() {
return secondName;
}
public void setSecondName(Stage secondName) {
this.secondName = secondName;
}
}
例如,我們想知道有關上述 HelloWorldConfiguration 對象的以下更改?
我的問題如下。
免責聲明。 我是JAXB2 Basics插件包的作者,其中包括JAXB2 Equals 插件。
如果您從 XML 模式生成您的類,那么JAXB2 Equals 插件在此用例中可能對您有用。
JAXB2 Equals 插件能夠生成對 JAXB 類實例進行深度結構遍歷值比較的equals
方法:
public boolean equals(Object object) {
final EqualsStrategy strategy = JAXBEqualsStrategy.INSTANCE;
return equals(null, null, object, strategy);
}
public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy strategy) {
if (!(object instanceof PurchaseOrderType)) {
return false;
}
if (this == object) {
return true;
}
final PurchaseOrderType that = ((PurchaseOrderType) object);
{
USAddress lhsShipTo;
lhsShipTo = this.getShipTo();
USAddress rhsShipTo;
rhsShipTo = that.getShipTo();
if (!strategy.equals(LocatorUtils.property(thisLocator, "shipTo", lhsShipTo), LocatorUtils.property(thatLocator, "shipTo", rhsShipTo), lhsShipTo, rhsShipTo)) {
return false;
}
}
{
USAddress lhsBillTo;
lhsBillTo = this.getBillTo();
USAddress rhsBillTo;
rhsBillTo = that.getBillTo();
if (!strategy.equals(LocatorUtils.property(thisLocator, "billTo", lhsBillTo), LocatorUtils.property(thatLocator, "billTo", rhsBillTo), lhsBillTo, rhsBillTo)) {
return false;
}
}
// ...
return true;
}
我希望你有這個想法。 您可以提供一個“定位器”來跟蹤被比較的事物的位置,以及一個對各個值進行比較的策略。
結果,您可以:
整個過程是無反射的,因此速度非常快。
下面是另一個項目的片段。 這是來自我比較對象“之前”和“之后”並記錄差異的測試之一。
final EqualsStrategy strategy = new org.jvnet.hyperjaxb3.lang.builder.ExtendedJAXBEqualsStrategy() {
@Override
public boolean equals(ObjectLocator leftLocator,
ObjectLocator rightLocator, Object lhs, Object rhs) {
if (!super.equals(leftLocator, rightLocator, lhs, rhs)) {
logger.debug("Objects are not equal.");
super.equals(leftLocator, rightLocator, lhs, rhs);
logger.debug("Left: "
+ (lhs == null ? "null" : lhs.toString()));
if (leftLocator != null) {
logger.debug("At [" + leftLocator.getPathAsString()
+ "].");
}
logger.debug("Right: "
+ (rhs == null ? "null" : rhs.toString()));
if (rightLocator != null) {
logger.debug("At [" + rightLocator.getPathAsString()
+ "].");
}
return false;
} else
{
return true;
}
}
};
另一方面,這種方法並不是真正的“差異”,因為您可能從 VCS 知道它。 它只是說有些不同,但不計算任何“最短編輯距離”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.