带有变量键

时间:2015-04-30 23:55:06

标签: java treemap comparable

我试图在Java中实现Fortune's algorithm,为了避免编写AVLTree,我决定使用带有BeachNode键的TreeMap。 BeachNode具有以下代码:

public abstract class BeachNode implements Comparable<BeachNode>{

static int idcounter=0;
int id;

public StatusNode(){
    //Allows for two nodes with the same coordinate
    id=idcounter;
    idcounter++;
}

@Override
public int compareTo(BeachNode s) {
    if(s.getX()<this.getX())
        return -1;
    if(s.getX()>this.getX())
        return 1;
    if(s.id<this.id)
        return 1;
    if(s.id>this.id)
        return -1;

    return 0;
}

public abstract double getX();
}

Intersection的getX()方法返回一个取决于扫描线当前高度的值 - 因此它会在执行过程中发生变化。

我的第一个问题: (我相当肯定答案是肯定的,但是心安会很好)

如果我确保对于任何两个BeachNodes A和B,signum(A.compareTo(B))保持不变,而A和B在海滩树中,那么即使compareTo背后发生了变化,TreeMap仍会起作用吗?

我的第二个问题:

我如何确保遵守这样的合同?

请注意,在Fortune's algorithm中,我们跟踪两个交叉点将遇到的扫描线位置 - 当扫描线到达其中一个位置时,其中一个交叉点被移除。

这意味着海滩树中的两个交叉点A和B将永远不会交叉位置,但在CircleEvent A.compareTo(B)中将返回0-干扰处理CircleEvent。合同将在CircleEvent期间短暂中断,这将删除一个交叉点。

这是我关于StackOverflow的第一个问题,如果它构成不当或不完整请通知我,我会尽力纠正它。

1 个答案:

答案 0 :(得分:1)

根据TreeMap documentation,树将根据compareTo方法进行排序,因此允许任何未在a.compareTo(b)的符号中反映的更改。但是,您还需要使用与equals相同的语义实现compareTo方法。如果您已经有compareTo方法,这非常简单:

public boolean equals(Object object) {
    if (!(object instanceof BeachNode)) {
        return false;
    }
    BeachNode other = (BeachNode) object;
    return this.compareTo(other) == 0;
}

而且,由于您要覆盖equals,因此您应该覆盖hashCode。这也很简单,因为您只使用几个字段来定义相等。

public int hashCode() {
    int hash = 1;
    hash = (17 * hash) + (Double getX()).hashCode());
    hash = (31 * hash) + id;
    return hash;
}

我不确定你的第二个问题,但由于两个交叉点的id应该保持不同,它们不相等吗?如果我错了,希望了解算法的人可以帮助你解决这个问题。