Java case equals方法中的hashCode方法支持wildchar
我有一个类,其对象将存储在hashmap hashset中 我需要为字段支持wildchar相等,因此我添加了check-inJava case equals方法中的hashCode方法支持wildchar,java,equals,hashcode,Java,Equals,Hashcode,我有一个类,其对象将存储在hashmap hashset中 我需要为字段支持wildchar相等,因此我添加了check-inequals方法。现在,如何基于这个参数构建hashcode方法?i、 e.如果我按照下面的代码进行计算,我将为通过equals方法的相等性检查的2个对象获得不同的hashcode 例如考虑以下类: public class Person { private String fname = ""; private String lname = "";
equals
方法。现在,如何基于这个参数构建hashcode方法?i、 e.如果我按照下面的代码进行计算,我将为通过equals方法的相等性检查的2个对象获得不同的hashcode
例如考虑以下类:
public class Person {
private String fname = "";
private String lname = "";
private String profession = "";
// getters & setters
@Override
public boolean equals(Object obj) {
if (fname == null) {
if (other.fname != null)
return false;
} else if (!fname.equals(other.fname) && !other.fname.equals("*") && !fname.equals("*"))
return false;
return true;
// similar for other fields
}
@Override
public int hashCode() {
return Objects.hashCode(this.fname, this.lname , this.profession);
}
}
编辑:
正如一些评论中指出的,应该有一个单独的方法来检查wildchar的相等性。这种方法的局限性在于,我无法为
set.contains
等方法获得正确的结果,因为它们在内部检查object.equals
。因此,我的set.contains
将返回false,即使我的对象通过了我的单独wildchar相等方法的相等测试。在hashCode()
中使用相同的逻辑是不可能的,因为我们不根据比较的对象计算哈希代码,而是根据当前对象状态进行计算您可以在
hashCode()
方法中返回一个常量值,但它效率不高,因此听起来不是一个好主意。您最初的问题来自这样一个事实,即您希望赋予一个不是设计用于
equals()
方法的职责:在对象的实际状态(即实际字段值)之外定义相等性。因此,不应使用
equals()
方法来执行通配符比较,而应为其编写专用方法 在hashCode()
中使用相同的逻辑是不可能的,因为我们不根据比较对象计算hash代码,而是根据当前对象状态计算它您可以在
hashCode()
方法中返回一个常量值,但它效率不高,因此听起来不是一个好主意。您最初的问题来自这样一个事实,即您希望赋予一个不是设计用于
equals()
方法的职责:在对象的实际状态(即实际字段值)之外定义相等性。因此,不应使用
equals()
方法来执行通配符比较,而应为其编写专用方法 您需要基于此自定义哈希代码。。从任何IDE生成默认的哈希代码方法,并根据您的逻辑对其进行自定义。我必须说,这是一个非常奇怪的equals实现。。特别是因为它甚至不会编译,你能告诉我们你的实际尝试吗?“这种方法的局限性是……”你的方法的局限性是它违反了equals和hashCode方法的形式要求,因此,当使用依赖它们的数据结构和算法时,您不应该期望正确的功能。.equals
方法必须是可传递的()。因此,如果您希望“a”.equals(“*”)返回true,并且“*”.equals(“b”)
返回true,那么必须使用“a”.equals(“b”)
返回true。您是否创建了类似于persons.contains(new Person(“*”,“myLastName”,“myprofessional”)
的东西来检查是否还有一个人使用“myLastName”
和“我的职业”
关于名字?为什么不对persons
进行流式处理,并检查persons.stream().anyMatch(p->p.getLname().equals(“myLastName”)&p.getProfession().endsWith(“myProfession”)代码>(省略了可读性的空检查)您需要基于此自定义哈希代码。。从任何IDE生成默认的哈希代码方法,并根据您的逻辑对其进行自定义。我必须说,这是一个非常奇怪的equals实现。。特别是因为它甚至不会编译,你能告诉我们你的实际尝试吗?“这种方法的局限性是……”你的方法的局限性是它违反了equals和hashCode方法的形式要求,因此,当使用依赖它们的数据结构和算法时,您不应该期望正确的功能。.equals
方法必须是可传递的()。因此,如果您希望“a”.equals(“*”)返回true,并且“*”.equals(“b”)
返回true,那么必须使用“a”.equals(“b”)
返回true。您是否创建了类似于persons.contains(new Person(“*”,“myLastName”,“myprofessional”)
的东西来检查是否还有一个人使用“myLastName”
和“我的职业”
关于名字?为什么不对persons
进行流式处理,并检查persons.stream().anyMatch(p->p.getLname().equals(“myLastName”)&p.getProfession().endsWith(“myProfession”)
(省略了对可读性的空检查)我理解,但这种方法的局限性是,我无法获得像set.contains
这样的方法的正确结果,因为它们在内部检查object.equals
。因此,我的set.contains
将返回false,即使我的对象通过了我单独方法的相等性测试。如果性能不是所说的问题,您可以在hashCode()
中返回一个常量,因此它在任何情况下都会工作,但您将失去哈希表的稳定性。很抱歉,有了这样的要求,很遗憾您处于困境。您是否无法使用与包含的不同的方法?问题在于设计:“a”
不等于“*”
,即使它匹配。同样,您的集合不包含该值。您是否可以在覆盖contains
方法的情况下生成集合的派生版本,即使在需要时也是如此?使用通配符的equals
方法违反了传递性规则,即当a
等于*
且*
等于b
时,则a