我像这样初始化HashSet:

private HashSet<Rule> ruleTable = new HashSet<Rule>();

我的equals()对象(抽象类hashCode()的子类)的TcpRuleRule方法如下所示:
@Override
public int hashCode() {
    // Ignore source Port for now
    return (this.getSrcPool() + ":" + this.getDstPool() + ":" + this.getProtocol() + ":" + this.dstTcp).hashCode();
}

@Override
public boolean equals(Object obj) {
    if (!(obj instanceof TcpRule))
        return false;
    if (obj == this)
        return true;

    TcpRule r = (TcpRule) obj;
    return (this.getSrcPool().equals(r.getSrcPool()) && this.getDstPool().equals(r.getDstPool()) && this.getProtocol().equals(r.getProtocol()) && this.getSrcTcp() == r.getSrcTcp() && this.getDstTcp() == r.getDstTcp());
}

我什至编写了一个简单的单元测试,没有给出任何错误:
@Test
public void equalsTest() {
    Pool srcPool = new Pool("PROXY");
    Pool dstPool = new Pool("WEB");
    int srcTcp = 54321;
    int dstTcp = 80;

    TcpRule r1 = new TcpRule(srcPool, dstPool, srcTcp, dstTcp);
    TcpRule r2 = r1;
    assert r1.equals(r2);

    TcpRule r3 = new TcpRule(srcPool, dstPool, srcTcp, dstTcp);
    TcpRule r4 = new TcpRule(srcPool, dstPool, srcTcp, dstTcp);
    assert r3.equals(r4);
}

@Test
public void hashCodeTest() {
    Pool srcPool = new Pool("PROXY");
    Pool dstPool = new Pool("WEB");
    int srcTcp = 54321;
    int dstTcp = 80;

    TcpRule r1 = new TcpRule(srcPool, dstPool, srcTcp, dstTcp);
    TcpRule r2 = new TcpRule(srcPool, dstPool, srcTcp, dstTcp);
    assert r1.hashCode() == r2.hashCode();

    HashSet<Rule> rules = new HashSet<Rule>();
    rules.add(r1);
    assert rules.contains(r1);

    assert rules.contains(r2);
}

在我的应用程序中,我有一个add()方法,我只需在Rule中添加一个HashSet对象:
@Override
public void add(Rule rule) {
    ruleTable.add(rule);
}

在另一种方法中,我检查HashSet中是否存在规则:
    @Override
public boolean isPermittedTcp(IpAddress sourceAddress, IpAddress destinationAddress, short srcTcp, short dstTcp) {
    Pool sourcePool = poolService.getPool(new Host(sourceAddress));
    Pool destinationPool = poolService.getPool(new Host(destinationAddress));
    Rule r = new TcpRule(sourcePool, destinationPool, srcTcp, dstTcp);
    log.info("Checking: " + r.toString());
    log.info("Hash-Code: " + r.hashCode());
    log.info("Hashes in ruleTable:");
    for(Rule rT : ruleTable) {
        log.info("" + rT.hashCode());
    }
    if(ruleTable.contains(r)) {
        log.info("Hash found!");
    } else {
        log.info("Hash not found!");
    }
    return ruleTable.contains(r);
}

日志消息指示Rule对象(r.hashCode())的哈希为-1313430269,并且HashSet(循环中为rT.hashCode())中的一个哈希也为-1313430269
但是ruleTable.contains(r)总是返回false。我究竟做错了什么?

我在StackOverflow上发现了类似的问题,但这些问题大多涉及equals()hashCode()方法没有(正确)被覆盖。我认为我已经正确实现了这两种方法。

最佳答案

您的问题是hashCode()equals()会执行而不是同意。
您的hashCode()实现基于池的toString(),但是equals()使用池类的.equals()
更改.equals()以比较用于生成哈希码的字符串。

09-05 15:33
查看更多