java - 如何实现键可变的键值对

标签 java treemap comparable

我正在编写一些代码来根据 2 个字段删除重复数据:

  1. 一串字符,我们称之为 UMI
  2. 整数数组

我创建了一个 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/

相关文章:

java - 使用反射生成的 Java 源代码

java - 读取 tar.gz 存档中 CSV 文件的内容

algorithm - 布置圆形 TreeMap 的算法是什么?

java - 比较方法(compareTo)在不同的JVM中返回不同的结果

java - netflix.feign 和 openfeign 之间的区别

java - JUnit 4 和异常暂停

java - 保留特殊订单/按 map 排序

Java Map 按值排序

java - 为什么我的书会说 Integer 的 compareTo 有一个 Object 参数?

java - 类似的接口(interface)