请参阅以下两个类DTO
和DTOWithOrdering
:
public class DTO {
private final String key;
private final long recordVersionNumber;
public DTO(String key) {
this.key = key;
this.recordVersionNumber = 0;
}
public DTO(String key, long recordVersionNumber) {
this.key = key;
this.recordVersionNumber = recordVersionNumber;
}
public String getKey() {
return key;
}
public long getRecordVersionNumber() {
return recordVersionNumber;
}
@Override
public String toString() {
return "Key: " + this.key + " Record Version Number: " + this.recordVersionNumber;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DTO that = (DTO) o;
return Objects.equal(this.key, that.key) &&
Objects.equal(this.recordVersionNumber, that.recordVersionNumber);
}
@Override
public int hashCode() {
return Objects.hashCode(key, recordVersionNumber);
}
public class DTOWithOrdering extends DTO implements Comparable<DTOWithOrdering> {
public DTOWithOrdering(String key, long recordVersionNumber) {
super(key, recordVersionNumber);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DTOWithOrdering other = (DTOWithOrdering) o;
if(this.getKey().equals(other.getKey())) {
if(this.getRecordVersionNumber() == other.getRecordVersionNumber()) {
return true;
} else if(this.getRecordVersionNumber() <= other.getRecordVersionNumber()) {
return true;
} else {
return false;
}
} {
return false;
}
}
@Override
public int compareTo(DTOWithOrdering other) {
if(this.getKey().equals(other.getKey())) {
if(this.getRecordVersionNumber() == other.getRecordVersionNumber()) {
return 0;
} else if(this.getRecordVersionNumber() <= other.getRecordVersionNumber()) {
return 0;
} else {
return -1;
}
} {
return -1;
}
}
}
DTOWIthOrdering
从DTO
延伸,并覆盖equals
和compareTo
方法。
当我创建TreeSet<DTOWIthOrdering>
并在此调用包含
TreeSet<DTOWithOrdering> treeSet = new TreeSet<DTOWithOrdering>(keyAndVersionList);
List<DTO> results = new ArrayList<DTO>();
for (DTO diff : diffs) {
if (treeSet.contains(new DTOWithOrdering(diff.getKey(), diff.getRecordVersionNumber())) == false) {
results.add(diff);
}
}
当我在我的程序中运行时,我可以看到treeSet包含2700多个实体,其中一个实体的密钥为0b3ae620-bbcf-347d-a9b4-87e6fd765cd7,recordVersionNumber为4
但是,其中一个diff实体包含相同的键,其recordVersionNumber为0。
当代码调用contains方法时,set返回值false。
奇怪的是,对于其他示例,其中键相等且TreeSet中的记录版本号更大,它返回true!
我的逻辑在这里有什么问题吗?
答案 0 :(得分:3)
以下是JavaDoc对Comparable
接口的引用:
int compareTo(T o)
将此对象与指定的订单对象进行比较。返回一个 负整数,零或正整数,因为此对象较少 比,等于或大于指定的对象。实施者 必须确保所有x和s的sgn(x.compareTo(y))== -sgn(y.compareTo(x)) 年。 (这意味着x.compareTo(y)必须抛出异常 y.compareTo(x)抛出异常。)
如果您返回-1
但永远不会返回1
,则属性为
sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
不能成立。因此,您对此方法的实现不符合规范,TreeSet
可能无法正常工作。