gpt4 book ai didi

Java HashSet 包含返回 false,即使覆盖了 equals() 和 hashCode()

转载 作者:搜寻专家 更新时间:2023-11-01 03:56:37 25 4
gpt4 key购买 nike

我这样初始化 HashSet:

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

equals()hashCode()我的方法 TcpRule对象(抽象类的子类 Rule )看起来像这样:

@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() 以比较用于生成哈希码的字符串。

关于Java HashSet 包含返回 false,即使覆盖了 equals() 和 hashCode(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31163105/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com