大家在什么业务场景使用对象作为 HashMap 的 key?

2022-12-13 21:33:56 +08:00
 yurong3333333333

如题,求助大佬

背景:搜索出一堆八股文在描述为什么要重写两个方法,但是没描述在什么样的业务场景中需要这么做,本人也没遇到过。

2410 次点击
所在节点    程序员
20 条回复
t202201
2022-12-13 21:39:37 +08:00
同问
TWorldIsNButThis
2022-12-13 21:40:14 +08:00
很少,最多是几个基础类型的 Pair / Triple 或者在高版本里,用 record

其实都帮你写好了 equals 和 hash code
golangLover
2022-12-13 21:43:20 +08:00
没用过。。。。
yesterdaysun
2022-12-13 21:56:02 +08:00
有时会用在缓存的 key 上, 比如这个缓存需要一个一个 id 加另一个 id 才是唯一的, 之前可能会要字符串连接之类的, 换成对象就比较好, 不过只是纯感觉, 没有测过两者性能有多大差, 更多是为了类型安全和简单性可读性, 反正有 lombok 或者 record, equals 和 hashcode 都是自动的
sunjiayao
2022-12-13 21:58:53 +08:00
最近用过的是把一个 SDK 的 Config 对象当做 Key
orangie
2022-12-13 22:04:29 +08:00
除了 Map ,还有 Set 这个集合也是需要使用 HashCode 的。Map 的 containsValue 方法应该也是要用到 hashCode 来快速比较的吧。
orangie
2022-12-13 22:11:14 +08:00
设想,如果一个 POJO 只重写了 equals ,没重写 hashCode ,那么两个对象可能因为内容是相同的所以 equals 是 true ,但是 openJDK 的默认 hashCode 实现是随机数(虽然 JDK 注释写的是内存地址),它们的 hashCode 应该是不同的,这种情况是荒谬的,不应该出现。
5200721
2022-12-13 22:14:18 +08:00
重写过一次,判断 Hive 库表的原信息和存储在 MySQL 中的 Hive 库表信息差异来更新 MySQL 中的数据。还踩了一个字符串对象为 null 和空串的坑。
yurong3333333333
2022-12-13 22:39:36 +08:00
@orangie 看清楚题目意思哈
orangie
2022-12-13 22:48:45 +08:00
如果一个对象有多个属性,而所有属性全部同时考虑在内才能判断唯一性,那么用对象本身(也就是它的 hashcode )作为 key 是唯一的选择,总不能为了有个字符串 key 把这个对象序列化吧?对应的数据库中表的情况就是所有字段形成了复合主键。但是好像很少会有这么设计的,倒是业务的中间过程有可能会出现这种情况。
wolfie
2022-12-13 23:14:53 +08:00
pair 、tripple + 1
组合 key
dqzcwxb
2022-12-13 23:41:41 +08:00
题外话,TreeMap 用的是 Comparable
zhouhu
2022-12-14 00:17:25 +08:00
hashCode 方法的返回(默认返回对象在内存中的地址)决定了对象在 HashMap 中的位置,equal (默认比较对象的内存地址)决定了两个对象是不是相等。要不要重写在于你的业务需求。
tedzhou1221
2022-12-14 09:05:02 +08:00
策略模式中,使用枚举类作为 HashMap 的 key
theniupa
2022-12-14 09:09:35 +08:00
HashMap 用对象做 key 的场景还没碰到过。。
只有用到过某些特定的场景需要多属性排序策略的时候 ,Comparable 对象做做 TreeMap 的 key ,比如 DirectByteBuffer 池
lmshl
2022-12-14 10:54:54 +08:00
挺常见的吧,比如有些场景下我会用 java.time.LocalDate 做 key
guyeu
2022-12-14 18:45:17 +08:00
鉴于 Java 不支持基本数据类型的泛型,所以没法不用对象当作 Map 的 key 。

以下正经表达:重写 hashcode 和 equals 方法,刚才搜了以下你说的八股文,它们描述的是,为什么在用到哈希表的情况下需要重写这两个方法,这个就能回答你的第一个问题,需要重写这两个方法的业务场景是可能或已经用了哈希表的场景,包括但不仅限于 HashMap, HashSet, HashTable, ConcurrentHashMap...

另外,用作 HashMap 的 key 的对象不拘泥于是什么类型,只要不是可变对象就不会出什么问题。业务中用的最多的是 String ,一些不讲究类型表达语义的编码里,经常会把其他的数据类型转成 String ,用作 HashMap 的 key ,在这些代码里,几乎就见不到其他类型作为 HashMap 的 key 。
imv2er
2022-12-14 20:57:36 +08:00
举个例子
人包含名字和钱。 给你一个 list 里面包含了很多人 ,又同一个人(名字相同),但是钱不同,你希望针对每一个人保留最后一条作为最终余额。
你可以选择将他们放到 hashmap 去重。此时你重写人的 hashcode 和 equal 方法能保证结果
aguesuka
2022-12-14 23:22:47 +08:00
@tedzhou1221 你应该使用 EnumMap 而不是 HashMap
zerofancy
2022-12-16 14:05:08 +08:00
安卓开发,activity 作为 WeakHashMap 的 key ,因为 key 是 weak 的,存储 activity 集合不发生内存泄漏

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/902303

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX