如何在Java中生成long类型哈希ID用于PostgreSQL数据库记录去重
可行实现方案
方案1:使用JDK内置MessageDigest实现64位哈希(无第三方依赖)
你可以直接用MD5或者SHA-256算法计算哈希后,取前8个字节转为long类型,完全符合long的取值范围要求。
代码示例:
import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class HashGenerator { private static final MessageDigest SHA_256_DIGEST; static { try { SHA_256_DIGEST = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("SHA-256算法不存在", e); } } public static long generateLongHash(String content) { byte[] hashBytes = SHA_256_DIGEST.digest(content.getBytes(StandardCharsets.UTF_8)); // 取前8个字节拼接为long long result = 0; for (int i = 0; i < 8; i++) { result = (result << 8) | (hashBytes[i] & 0xff); } return result; } }
你可以把入参改成要哈希的业务字段拼接后的字符串即可,哈希冲突概率和64位哈希的理论值一致,你已经自行处理冲突逻辑的话完全够用。
方案2:使用MurmurHash 64位版本(性能更优,适合高频率调用场景)
MurmurHash是专门为业务场景设计的非加密哈希算法,性能比SHA/MD5高很多,非常适合去重场景,Guava库已经内置了实现:
import com.google.common.hash.Hashing; import java.nio.charset.StandardCharsets; public class HashGenerator { public static long generateLongHash(String content) { return Hashing.murmur3_128().hashString(content, StandardCharsets.UTF_8).asLong(); } }
如果不想引入Guava,也可以直接找MurmurHash 64位的Java纯实现复制到项目中,代码量很小只有几十行。
方案3:组合多个int哈希值转为long(极简实现,性能最高)
如果对哈希分布要求不高,也可以把两个不同规则的int哈希值拼接为long,实现非常简单:
import java.util.Objects; public class HashGenerator { public static long generateLongHash(Object... fields) { int hash1 = Objects.hash(fields); int hash2 = Objects.hash(fields.getClass(), hash1); return ((long) hash1 << 32) | (hash2 & 0xffffffffL); } }
这个方案性能最高,但是哈希冲突概率比前两个方案高,你如果已经有冲突兼容逻辑的话也可以使用。
注意事项
- 所有方案生成的long值可能为负数,存入PostgreSQL时可以直接用
bigint类型存储,不需要额外处理 - 如果需要避免负数,可以在返回结果前和
0x7fffffffffffffffL做按位与操作,相当于取绝对值,不会增加冲突概率
内容的提问来源于stack exchange,提问作者Jessi
相关产品推荐
相关产品推荐

