处理数据的过程中,希望对数据进行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很容易碰撞的。