我正在编写一些代码来根据 2 个字段删除重复数据:
- 一串字符,我们称之为 UMI
- 整数数组
我创建了一个 POJO 来保存这些数据并作为 TreeMap
的键。完整的数据集保存在值中 - 这样我只将相关数据保留在内存中。
但是,下一个要求是 UMI 和整数具有可变性。例如,基于可变性(不匹配)为 1 的 UMI,以下两条数据将被视为重复。
a. “AAA”,[200,300]
b. “ABA”,[200,300]
类似地,如果不匹配余量为 2,则以下内容将被视为基于整数数组的重复项。
a. “AAA”,[201,300]
b. “AAA”,[203,300]
我当前的尝试是让这个 POJO 实现 Comparable 接口(interface),并尝试使用compareTo 方法来考虑可变性:
public class UMIPrimoKey implements Comparable<UMIPrimoKey> {
private final String UMI;
private final int[] ints;
private final int umiMisMatch;
private final int posMisMatch;
public UMIPrimoKey(String UMI, int[] ints, int umiMisMatch, int posMisMatch) {
this.UMI = UMI;
this.ints = ints;
this.umiMisMatch = umiMisMatch;
this.posMisMatch = posMisMatch;
}
@Override
public int compareTo(UMIPrimoKey o) {
if (!Arrays.equals(ints, o.ints)) {
if (ints.length == o.ints.length) {
for (int i = 0; i < ints.length; i++) {
if (Math.abs(ints[i] - o.ints[i]) > posMisMatch) {
return -1;
}
}
} else {
return -1;
}
}
if (XsamStringUtils.numberOfDifferences(UMI, o.UMI) <= umiMisMatch) {
return 0;
}
return 1;
}
}
XsamStringUtils.numberOfDifferences
只是一个简单的静态方法,用于计算两个 UMI 之间的差异数量。
如果数组中任意两个整数的差异大于允许的不匹配值 (posMisMatch
),我将返回 -1。如果允许整数,并且 UMI 中不匹配的数量小于 umiMisMatch
指定的允许数量,则返回 0。
否则,由于 UMI 不匹配,因此返回 1。
然后我在考虑了 compareTo
方法的 TreeMap
中使用了它。
这在我的单元测试中有效,添加了少量 UMIPrimoKey
,但在运行已完成的程序时我得到了一些奇怪的结果。这可能是由于此处概述的方法的规则所致:https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html但我发现很难调整代码以考虑规则。
感谢任何指导,感谢您的阅读!
最佳答案
根据docs比较:
The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)
The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.
Finally, the implementor must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.
我认为这对您的代码来说是不正确的,这可能会导致 get 函数找不到您的条目出现问题
关于java - 如何实现键可变的键值对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54074856/