[英]How can I take into consideration the object itself when calculating a hash for an object in Java?
当我遇到这个问题时,我正在研究一些算法问题,这对我来说似乎很有趣。 如果我有两个列表(所以两个不同的对象),具有相同的值,哈希码是相同的。 经过一番阅读,我明白这就是它应该表现的方式。 例如:
List<String> lst1 = new LinkedList<>(Arrays.asList("str1", "str2"));
List<String> lst2 = new LinkedList<>(Arrays.asList("str1", "str2"));
System.out.println(lst1.hashCode() + " " + lst2.hashCode());
...........
Result: 2640541 2640541
例如,我的目的是区分列表中的 lst1 和 lst2 。
在计算某些东西的哈希码时,是否有一个结构(例如 HashSet)考虑实际的 object 而不仅仅是 object 内部的值?
是的,您可以使用 java 的java.util.IdentityHashMap或番石榴的身份 hash set 。
两个列表的哈希值必须相等,因为对象是相等的。 但是上面设置的标识 map 是基于列表对象的标识,而不是它们的 hash。
如果我有两个列表(所以两个不同的对象),具有相同的值,哈希码是相同的。 经过一番阅读,我明白这就是它应该表现的方式。
是的,这是java.util.List
规范的一部分。
在计算某些东西的哈希码时,是否有一个结构(例如 HashSet)考虑实际的 object 而不仅仅是 object 内部的值?
例如,我的目的是区分列表中的 lst1 和 lst2
目前尚不清楚“在列表中”是什么意思。 例如, Collection.contains()
和List.equals()
是在术语或成员的equals()
方法中定义的,同样是List.remove(Object)
的行为。 尽管对象不同,但您的两个List
将彼此比较,因此这些方法不会直接区分它们,也不会作为另一个列表的成员。 但是,您始终可以比较它们的引用相等性 ( ==
),以确定它们不是相同的 object 尽管彼此是equals()
。
至于将成员的 object 身份考虑在内的集合,您可以考虑java.util.IdentityHashMap
。 两个这样的映射,其键和关联值彼此成对equals()
但不相同,不会相互比较equals()
。 此类套件通常具有不同的 hash 代码,但不能保证这一点。 但是请注意, IdentityHashMap
文档中的警告尽管它实现了Map
API,但许多行为细节与该接口的要求不一致。
另请注意
以上大部分内容仅与 collections 相关,其成员属于覆盖equals()
和hashCode()
的类型。 Object
的实现或继承于引用相等的基础上区分对象,因此普通的 collections 类对您来说没有什么意外。
不需要相同的字符串文字来表示不同的对象,因此示例代码中的lst1
和lst2
实际上可能包含相同的元素,在引用相等意义上。
通常不在 collections 中,因为您通常希望两个具有所有相同项目的 collections 相等(这就是为什么他们像这样实现它 - equals 将返回 true 并且 hash 代码相同)。
您可以子类化一个列表并且让它不这样做,它不会被广泛使用,并且如果其他程序员阅读您的代码会引起很多混乱。 在这种情况下,您只需要 equals 返回 == 和 hashCode 的结果以返回引用的 integer 值(与 Object.equals 所做的相同)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.