我在StringBuffer对象可以是TreeSet中的键吗?上找到了这个评论
“Java中的Maps使用了2种标识策略(或多或少)。
散列:输入"Foo“被转换为尽可能好的尝试,以生成唯一访问数组索引的数字。(纯粹主义者,请不要虐待我,我是故意简化的)。此索引是存储值的位置。有可能"Foo“和"Bar”实际上生成相同的索引值,这意味着它们都将被映射到相同的数组位置。很明显,这是不能工作的,所以这就是"equals()“方法出现的原因;它用于消除歧义。
比较:通过使用比较方法,您不需要这个额外的消歧步骤,因为比较一开始就不会产生这种冲突。唯一的键"Foo“等于"Foo”。但是,一个非常好的主意是,为了一致性起见,您是否可以将"equals()“定义为compareTo() == 0。这不是一个要求。“
我的问题如下:如果我的类实现了可比较的,那么这是否意味着我不必重写等于和hashcode方法来使用我的对象作为哈希集合中的键。例如
class Person implements Comparable<Person> {
int id;
String name;
public Person(int id, String name) {
this.id=id;
this.name=name;
}
public int compareTo(Person other) {
return this.id-other.id;
}
}现在,我可以在Hashable集合中使用我的Person对象了吗?
发布于 2013-08-22 23:49:55
这篇文章是关于TreeSet的。树集是一棵树,每个节点都有一个位置,它的值与树中的其他值相比较。
hashTable将键/值对存储在哈希表中。使用Hashtable时,可以指定用作键的对象,以及要链接到该键的值。然后对键进行散列,并将得到的哈希代码用作将值存储在表中的索引。
Hashable和TreeSet的不同之处在于树集不需要hashCode,它只需要知道是否需要在树中左或右获取项。为此,您可以使用“比较”,仅此而已。
在hashTable中,比较就足够了,因为它的构建方式不同,每个对象都可以通过散列而不是通过将其与集合中的项进行比较来到达其单元格。
因此,答案是否定的,您可以在散列表中使用Person,只需使用compareTo。为此,必须重写hashCode()和equals()。
我还建议您阅读这关于哈希表的文章。
发布于 2013-08-22 23:59:18
HashTable确实使用了等于和hashCode。每个班级都有这些方法。如果不实现它们,就继承它们。
是否需要实现它们取决于继承的版本是否适合您的目的。特别是,由于Person没有指定的超类,所以它继承了Object方法。这意味着Person对象只等于它自己。
是否需要将两个不同的Person对象视为与HashTable键相等的对象?
发布于 2013-08-22 23:56:10
如果我的类实现了类似的,那么这是否意味着我不必重写等于和hashcode方法来使用我的对象作为哈希集合中的键。例如
不,您仍然需要实现equals()和hashCode()。这些方法执行非常不同的功能,不能被compareTo()所取代。
equals()根据对象的相等性返回布尔值。这通常是身份平等,而不是字段平等。这可能与用于比较compareTo(...)中的对象的字段非常不同,尽管如果它对实体有意义,则equals()方法可以是:
@重写公共布尔值等于(Object obj) { if (obj == null \ obj.getClass() != getClass()) {返回false;}{返回compareTo((Person)obj) == 0;}}hashCode()为实例返回一个整数值,该值在哈希表中用于计算它应该放置的桶。没有任何相同的方法可以从compareTo(...)中获取这个值。https://stackoverflow.com/questions/18392468
复制相似问题