gpt4 book ai didi

java - 我将如何递归地比较两个相同但未知类型的 Java 对象的字段值?

转载 作者:数据小太阳 更新时间:2023-10-29 02:40:26 27 4
gpt4 key购买 nike

我们正在使用 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 对象的以下更改?

  • 列表中有附加的“HelloWorldObject”项目(必须在屏幕上打印该项目及其属性)
  • 位置 n 的“HelloWorldObject”有一个新的“firstName”值(更改的字段或 XML 元素的名称及其值应被打印)
  • 新的“HelloWorldObject”列表缩短了 2 个以下元素(缺少的元素必须与所有属性和值一起打印)

我的问题如下。

  • 您是通过在 Java 对象级别上进行反射还是比较两个不同的 XML 文件来解决这个问题?
  • 是否有图书馆已经为我做了类似的事情?在 XML 或 Java 对象级别?
  • 有什么例子吗?

最佳答案

免责声明。我是 JAXB2 Basics 的作者包含 JAXB2 Equals plugin 的插件包.


如果您从 XML 模式生成类,则 JAXB2 Equals plugin在此用例中可能对您有用。

JAXB2 Equals plugin能够生成 equals 方法,这些方法对 JAXB 类实例进行深度结构遍历值比较:

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

我希望你已经明白了。您可以提供一个“定位器”来跟踪被比较事物的位置,并提供一个策略来比较各个值。

结果您可以:

  • 对模式派生的 JAXB 类实例进行深入比较。
  • 了解什么不同(精确值)。​​
  • 知道哪里有差异(对象结构中的确切位置)。

而且整个过程是无反射的,因此非常快。

以下是来自 another project 的片段.这是我比较对象“之前”和“之后”并记录差异的测试之一。

    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 中了解到的那样。它只说有什么不同,但不计算任何“最短编辑距离”。

关于java - 我将如何递归地比较两个相同但未知类型的 Java 对象的字段值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26651208/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com