gpt4 book ai didi

java - 装饰器模式和哈希码

转载 作者:行者123 更新时间:2023-12-04 05:14:19 27 4
gpt4 key购买 nike

我在我的一个程序中使用装饰器模式来装饰具有不同毕业要求的类(class)。几个例子:

new BasicCourse("Course Foo", 1);  // parameters are name and credits

new DisciplinaryBreadth(DBR.MATH, new BasicCourse("Course Foo", 1));

new IntroToHumanities(IHUM.FIRST_QUARTER,
new ProgramInWritingAndRhetoric(PWR.FIRST_YEAR,
new BasicCourse("Course Bar", 2)));

new ProgramInWritingAndRhetoric(PWR.FIRST_YEAR,
new IntroToHumanities(IHUM.FIRST_QUARTER,
new BasicCourse("Course Bar", 2)));

后两者在交换性质上是相同的。

我正在实现 hashcode()equals() ,以便我可以在 HashMap 中使用类(class)。我不得不更改 Eclipse 自动生成的 equals 函数,以便可交换的类(class)彼此相等。我对 hashcode 生成的理解不及我对 equals 的理解,所以我想知道我是否需要对 hashcode 函数做同样的事情。

以下是 Eclipse 为每个装饰器提供的信息:
    @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((inner == null) ? 0 : inner.hashCode());
result = prime * result
+ ((requirement == null) ? 0 : requirement.hashCode());
return result;
}

这会为交换类(class)产生相同的哈希吗?

编辑
每个装饰者都有一个 requirement与具有该装饰器的类(class)满足的要求相对应的变量。例如,DisciplinaryBreadth 类有一个类 DBR 的要求,它是可能的 Disciplinary Breadth 要求的枚举。 ProgramInWritingAndRhetoric 类有一个类 PWR 的要求,它是可能的 Program in Writing 和 Rhetoric 要求的枚举。等等。

每个装饰器中的需求变量是一个不同的枚举。所有类(class)都实现了获得各种毕业要求的方法(例如 getDbrs()getIhum() )。

装饰者为除他们定义的要求之外的所有要求调用其内部类(class)的方法。例如 IntroToHumanities 类调用 inner.getDbrs()inner.getPwr() ,但对其 getIhum() 使用它的需求变量方法。他们还为 getName() 调用了他们内部类(class)的方法。和 getCredits()方法,而 BasicCourse 类使用在其构造函数中设置的最终成员定义这些方法。
inner变量只是每个装饰器包装的内部类(class)。内部和需求变量在每个装饰器的构造函数中设置并且是最终的。

这是 ProgramInWritingAndRhetoric 类的 equals 方法:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Course))
return false;
Course other = (Course) obj;
if (getName() == null) {
if (other.getName() != null)
return false;
} else if (!getName().equals(other.getName()))
return false;
if (getCredits() != other.getCredits())
return false;
if (!getDbrs().equals(other.getDbrs()))
return false;
if (!requirement.equals(other.getPwr()))
return false;
if (!getIhum().equals(other.getIhum()))
return false;
if (!getEc().equals(other.getEc())) //another Graduation Requirement
return false;
return true;
}

我跳过了一些对 null 的检查,因为我在构造函数中检查了它们,例如,你不能使用 null IHUM 创建 Course。其他毕业要求实现也类似,唯一的区别是要求变量的使用位置。

最佳答案

@Eva 我不同意你应该让你的 IDE 生成你的哈希码方法的建议,但也许我是老式的。

基本上,在生成散列时,您的目标是(在合理可行的范围内)基于对象的成员变量获得一组分布良好且唯一的散列。

因此,您应该获取成员变量的值(其中原始值)或哈希码(当是复杂对象时),并使用它们以分布良好的方式计算哈希码(因此通常使用素数作为乘数) ) 并且不太可能引起碰撞。

因此,合理的 hashCode() 将使用与您的 equals 方法相同的成员变量,但取值/哈希值并将它们与素数相乘。

请记住,唯一的、分布良好的散列的唯一保证是提前知道可能的所有对象,在这种情况下,您实际上可以预先分配散列,但这很少是有效的解决方案。

这很好地解释了您要实现的目标 - http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/

关于java - 装饰器模式和哈希码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14484705/

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