如何在使用杰克逊映射时适当地覆盖 equals(Object o)
How to appropriately override equals(Object o) while using jackson mapping
JSON :
"ABCD": [
{
"xyz": 3,
"abc": 4,
"date": {
"start": 1462341600000,
"stop": 1462513680000
}
}
...similar sub parts
]
Datatype 已定义:我已尝试为 json 定义相应的数据类型,如下所示 [忽略其他字段现在]:
public class Test {
TestDate testDate = new TestDate();
private Long start = testDate.startTime;
private Long stop = testDate.expiryTime;
public class TestDate {
private Long startTime;
private Long expiryTime;
// getter and setter implemented here
}
}
现在,我感到困惑的是如何覆盖 equals
方法来满足 start 和 stop[=53= 的检查] JSON.
的参数
案例 1: 比较在测试中声明的变量 start
和 stop
class 并赋值给TestDate对应的参数。如:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test test = (Test) o;
// Below is what I am concerned about
if (stop != null ? !stop.equals(test.stop) : test.stop != null) return false;
if (start != null ? !start.equals(test.start) : test.start != null) return false;
}
或
案例2: 只需使用在测试class中创建的对象testDate
进行比较。如:
if (testDate != null ? !testDate.equals(test.testDate) : test.testDate != null) return false;
疑惑 :
- 案例 2 是否足以满足 案例 1?
- 如果不是,有什么区别?
- 如果是,哪一个是更好的做法?
正在寻找更多统计信息来说明为什么在代码复杂性和可重用性方面使用案例 2 而不是案例 1。
正确的方法是让 Test
关注自己的领域,所以它应该像你所做的那样根据 o
检查自己,但在我看来 start
/stop
字段不应该存在。在 o
检查之后,你的 Test
equals 方法应该以 identity/null 检查 testDate
结束,如果两者都是非 null 并且不是同一个对象,那么它应该委托给(和return) TestDate class.
上的 equals 实现
所以基本上 案例 2 是正确的方法,但我会重新考虑测试时启动和停止的存在。此外,案例 2 语句可以很容易地重构为简单的 return 而无需 if - 不确定我是否见过三元组?作为 ; 之前的 if 条件。课程的马,但我认为以下内容更容易阅读:
return (testDate == test.testDate) || (testDate != null && testDate.equals(test.testDate));
在 Test
class 上具有 start
/stop
字段意味着 TestDate
的实现正在泄漏到 Test
class。如果您决定对 TestDate
进行一些重大更改(可能为了论证而不是将值存储为本地化日期),那么您会打破案例 1 下的 Test
class 但案例 2 会幸免于难,因此案例 2 更加稳健。
另一个考虑因素是 hashCode
方法 - 在 Test
上 start
/stop
字段的情况 1 下的上述问题实际上加倍了,因为你应该真正以一致的方式实施 hashCode
。
随着系统变得越来越复杂,解决此类问题所花费的时间很快就会变得非常重要,而且更容易出错。
JSON :
"ABCD": [
{
"xyz": 3,
"abc": 4,
"date": {
"start": 1462341600000,
"stop": 1462513680000
}
}
...similar sub parts
]
Datatype 已定义:我已尝试为 json 定义相应的数据类型,如下所示 [忽略其他字段现在]:
public class Test {
TestDate testDate = new TestDate();
private Long start = testDate.startTime;
private Long stop = testDate.expiryTime;
public class TestDate {
private Long startTime;
private Long expiryTime;
// getter and setter implemented here
}
}
现在,我感到困惑的是如何覆盖 equals
方法来满足 start 和 stop[=53= 的检查] JSON.
案例 1: 比较在测试中声明的变量 start
和 stop
class 并赋值给TestDate对应的参数。如:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test test = (Test) o;
// Below is what I am concerned about
if (stop != null ? !stop.equals(test.stop) : test.stop != null) return false;
if (start != null ? !start.equals(test.start) : test.start != null) return false;
}
或
案例2: 只需使用在测试class中创建的对象testDate
进行比较。如:
if (testDate != null ? !testDate.equals(test.testDate) : test.testDate != null) return false;
疑惑 :
- 案例 2 是否足以满足 案例 1?
- 如果不是,有什么区别?
- 如果是,哪一个是更好的做法?
正在寻找更多统计信息来说明为什么在代码复杂性和可重用性方面使用案例 2 而不是案例 1。
正确的方法是让 Test
关注自己的领域,所以它应该像你所做的那样根据 o
检查自己,但在我看来 start
/stop
字段不应该存在。在 o
检查之后,你的 Test
equals 方法应该以 identity/null 检查 testDate
结束,如果两者都是非 null 并且不是同一个对象,那么它应该委托给(和return) TestDate class.
所以基本上 案例 2 是正确的方法,但我会重新考虑测试时启动和停止的存在。此外,案例 2 语句可以很容易地重构为简单的 return 而无需 if - 不确定我是否见过三元组?作为 ; 之前的 if 条件。课程的马,但我认为以下内容更容易阅读:
return (testDate == test.testDate) || (testDate != null && testDate.equals(test.testDate));
在 Test
class 上具有 start
/stop
字段意味着 TestDate
的实现正在泄漏到 Test
class。如果您决定对 TestDate
进行一些重大更改(可能为了论证而不是将值存储为本地化日期),那么您会打破案例 1 下的 Test
class 但案例 2 会幸免于难,因此案例 2 更加稳健。
另一个考虑因素是 hashCode
方法 - 在 Test
上 start
/stop
字段的情况 1 下的上述问题实际上加倍了,因为你应该真正以一致的方式实施 hashCode
。
随着系统变得越来越复杂,解决此类问题所花费的时间很快就会变得非常重要,而且更容易出错。