是否可以为使用 jaxb 生成的 类 生成 equals 和 compareTo 方法
Is it possible to generate equals and compareTo methods for classes generated with jaxb
是否可以为使用 jaxb 生成的 类 生成 equals 和 compareTo 方法,我使用 jaxb 从模式生成 类。这些 类 实际上有允许它们被唯一标识的 guid,但是我如何实现一个 equals/compare 方法,以便 Collection 类 如 Set 能够识别同一实体的重复实例?
免责声明:我是 jaxb2-basics
的作者,它提供了能够生成 hashCode
和 equals
方法的 JAXB2 插件。
这是 Maven 的用法示例:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<extension>true</extension>
<args>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>...</version>
</plugin>
</plugins>
</configuration>
</plugin>
(请参阅 Ant 的 documentation。)
您可以使用 -XsimpleHashCode
and -XsimpleEquals
生成无运行时 hashCode
和 equals
方法(内联哈希码或等于计算)或 -XhashCode
/-Xequals
生成 "strategic" hashCode
和 equals
方法(散列 code/equals 计算委托给传递的策略方法)。
这是 -XsimpleHashCode
生成的内容:
public class Customer {
...
public int hashCode() {
int currentHashCode = 1;
{
currentHashCode = (currentHashCode* 31);
String theAddress;
theAddress = this.getAddress();
if (theAddress!= null) {
currentHashCode += theAddress.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
Boolean theBlueEyes;
theBlueEyes = this.isBlueEyes();
if (theBlueEyes!= null) {
currentHashCode += theBlueEyes.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
String theFamilyName;
theFamilyName = this.getFamilyName();
if (theFamilyName!= null) {
currentHashCode += theFamilyName.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
String theGivenName;
theGivenName = this.getGivenName();
if (theGivenName!= null) {
currentHashCode += theGivenName.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
List<String> theMiddleInitials;
theMiddleInitials = (this.isSetMiddleInitials()?this.getMiddleInitials():null);
if (theMiddleInitials!= null) {
currentHashCode += theMiddleInitials.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
String thePostCode;
thePostCode = this.getPostCode();
if (thePostCode!= null) {
currentHashCode += thePostCode.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
boolean theSingle;
theSingle = this.isSingle();
currentHashCode += (theSingle? 1231 : 1237);
}
return currentHashCode;
}
}
这是 -XhashCode
生成的内容:
public class Customer implements HashCode
{
...
public int hashCode(ObjectLocator locator, HashCodeStrategy strategy) {
int currentHashCode = 1;
{
String theAddress;
theAddress = this.getAddress();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "address", theAddress), currentHashCode, theAddress);
}
{
Boolean theBlueEyes;
theBlueEyes = this.isBlueEyes();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "blueEyes", theBlueEyes), currentHashCode, theBlueEyes);
}
{
String theFamilyName;
theFamilyName = this.getFamilyName();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "familyName", theFamilyName), currentHashCode, theFamilyName);
}
{
String theGivenName;
theGivenName = this.getGivenName();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "givenName", theGivenName), currentHashCode, theGivenName);
}
{
List<String> theMiddleInitials;
theMiddleInitials = (this.isSetMiddleInitials()?this.getMiddleInitials():null);
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "middleInitials", theMiddleInitials), currentHashCode, theMiddleInitials);
}
{
String thePostCode;
thePostCode = this.getPostCode();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "postCode", thePostCode), currentHashCode, thePostCode);
}
{
boolean theSingle;
theSingle = this.isSingle();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "single", theSingle), currentHashCode, theSingle);
}
return currentHashCode;
}
public int hashCode() {
final HashCodeStrategy strategy = JAXBHashCodeStrategy.INSTANCE;
return this.hashCode(null, strategy);
}
}
从我的 PoV 来看,"strategic" 版本更强大。 类 实施 HashCode
或 Equals
接受定位器和散列 code/equals 策略的接口。这允许您从外部控制哈希码计算或比较。我经常在单元测试中使用它,不仅要检查两个对象是否相等,还要找出它们到底在哪里不同。
两个插件都生成无反射方法(这对性能至关重要)。他们还考虑了 JAXB 特殊情况,例如 JAXBElement
s、原始数组等。
好的,这是另一种方法。
您可以使用 -XcodeInjector
插件添加 hashCode
和 equals
方法。
看到这个问题:
Inserting code with XJC+xsd+jxb using the options " -Xinject-code -extension "
类似于:
<jxb:bindings schemaLocation="schema.xsd">
<jxb:bindings node="/xs:schema/xs:complexType[@name='MyItemType']">
<ci:code>
@Override
public int hashCode() { return guid == null? 0 : guid.hashCode();}
</ci:code>
</jxb:bindings>
</jxb:bindings>
如果这还不够好,请考虑 filing an issue in JAXB2-Basics ("Allow selecting properties for hashCode/equals") 或实施您自己的插件。
是否可以为使用 jaxb 生成的 类 生成 equals 和 compareTo 方法,我使用 jaxb 从模式生成 类。这些 类 实际上有允许它们被唯一标识的 guid,但是我如何实现一个 equals/compare 方法,以便 Collection 类 如 Set 能够识别同一实体的重复实例?
免责声明:我是 jaxb2-basics
的作者,它提供了能够生成 hashCode
和 equals
方法的 JAXB2 插件。
这是 Maven 的用法示例:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<extension>true</extension>
<args>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>...</version>
</plugin>
</plugins>
</configuration>
</plugin>
(请参阅 Ant 的 documentation。)
您可以使用 -XsimpleHashCode
and -XsimpleEquals
生成无运行时 hashCode
和 equals
方法(内联哈希码或等于计算)或 -XhashCode
/-Xequals
生成 "strategic" hashCode
和 equals
方法(散列 code/equals 计算委托给传递的策略方法)。
这是 -XsimpleHashCode
生成的内容:
public class Customer {
...
public int hashCode() {
int currentHashCode = 1;
{
currentHashCode = (currentHashCode* 31);
String theAddress;
theAddress = this.getAddress();
if (theAddress!= null) {
currentHashCode += theAddress.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
Boolean theBlueEyes;
theBlueEyes = this.isBlueEyes();
if (theBlueEyes!= null) {
currentHashCode += theBlueEyes.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
String theFamilyName;
theFamilyName = this.getFamilyName();
if (theFamilyName!= null) {
currentHashCode += theFamilyName.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
String theGivenName;
theGivenName = this.getGivenName();
if (theGivenName!= null) {
currentHashCode += theGivenName.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
List<String> theMiddleInitials;
theMiddleInitials = (this.isSetMiddleInitials()?this.getMiddleInitials():null);
if (theMiddleInitials!= null) {
currentHashCode += theMiddleInitials.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
String thePostCode;
thePostCode = this.getPostCode();
if (thePostCode!= null) {
currentHashCode += thePostCode.hashCode();
}
}
{
currentHashCode = (currentHashCode* 31);
boolean theSingle;
theSingle = this.isSingle();
currentHashCode += (theSingle? 1231 : 1237);
}
return currentHashCode;
}
}
这是 -XhashCode
生成的内容:
public class Customer implements HashCode
{
...
public int hashCode(ObjectLocator locator, HashCodeStrategy strategy) {
int currentHashCode = 1;
{
String theAddress;
theAddress = this.getAddress();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "address", theAddress), currentHashCode, theAddress);
}
{
Boolean theBlueEyes;
theBlueEyes = this.isBlueEyes();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "blueEyes", theBlueEyes), currentHashCode, theBlueEyes);
}
{
String theFamilyName;
theFamilyName = this.getFamilyName();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "familyName", theFamilyName), currentHashCode, theFamilyName);
}
{
String theGivenName;
theGivenName = this.getGivenName();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "givenName", theGivenName), currentHashCode, theGivenName);
}
{
List<String> theMiddleInitials;
theMiddleInitials = (this.isSetMiddleInitials()?this.getMiddleInitials():null);
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "middleInitials", theMiddleInitials), currentHashCode, theMiddleInitials);
}
{
String thePostCode;
thePostCode = this.getPostCode();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "postCode", thePostCode), currentHashCode, thePostCode);
}
{
boolean theSingle;
theSingle = this.isSingle();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "single", theSingle), currentHashCode, theSingle);
}
return currentHashCode;
}
public int hashCode() {
final HashCodeStrategy strategy = JAXBHashCodeStrategy.INSTANCE;
return this.hashCode(null, strategy);
}
}
从我的 PoV 来看,"strategic" 版本更强大。 类 实施 HashCode
或 Equals
接受定位器和散列 code/equals 策略的接口。这允许您从外部控制哈希码计算或比较。我经常在单元测试中使用它,不仅要检查两个对象是否相等,还要找出它们到底在哪里不同。
两个插件都生成无反射方法(这对性能至关重要)。他们还考虑了 JAXB 特殊情况,例如 JAXBElement
s、原始数组等。
好的,这是另一种方法。
您可以使用 -XcodeInjector
插件添加 hashCode
和 equals
方法。
看到这个问题:
Inserting code with XJC+xsd+jxb using the options " -Xinject-code -extension "
类似于:
<jxb:bindings schemaLocation="schema.xsd">
<jxb:bindings node="/xs:schema/xs:complexType[@name='MyItemType']">
<ci:code>
@Override
public int hashCode() { return guid == null? 0 : guid.hashCode();}
</ci:code>
</jxb:bindings>
</jxb:bindings>
如果这还不够好,请考虑 filing an issue in JAXB2-Basics ("Allow selecting properties for hashCode/equals") 或实施您自己的插件。