慎用HashCode作为Unique Key

处理数据的过程中,希望对数据进行groupBy操作。举个例子,data的组成是<month, baseId, amount>。

数据A = <"2019-03","195",100>

数据B = <"2019-04","185", 200>

数据C = <"2019-03","195", 300>

数据D = <"2019-04","185", 400>

希望算出相同<month, baseId>的金额之和,其实如果用mysql就很好解决:

SELECT sum(amount) FROM data GROUP BY month, baseId

但是在java代码中怎么办呢?可以考虑用到 Java8 的流特性:

Map<String, List<XXX>> grouped = list.stream()
            .collect(groupingBy(keyGenerator::buildKey));

可以把相同<month, baseId>作为一个唯一的键值,根据键值来汇总相同<month, baseId>的数据。

那么如何生成唯一的键值呢?其实如果不考虑性能因素,直接字符串拼接,类似于“month-baseId",就可以作为一个key了。但是有的人就想,是不是可以采取类似于MD5的思路,使用<month, baseId>生成一个哈希值,作为唯一键值呢?

注意:请不要使用HashCode生成唯一键值。连MD5都有可能发生碰撞,使得2个文件加密出一样的值。更何况区区一个哈希值……举个例子:

public static void main(String[] args) {
        System.out.println(Objects.hash("2019-03", "195"));
        System.out.println(Objects.hash("2019-04", "185"));
    }

输出是

-1946385468
-1946385468

所以使用hashCode很容易碰撞的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值