我想了解如何从java对象的集合中生成唯一的id(String / Number等),这些对象可以是各种数据类型,如String,BigDecimal,org.joda.time.LocalDate或org .joda.time.LocalDateTime或任何自定义java对象。
生成的id应该基于java对象中的值,以便为具有相同值的两个集合生成相同的id。类似于sql group by子句的东西。我想从group by(col1,col2,col3)生成一个唯一的id,其中col1,col2和col3可以是任何数据类型。
答案 0 :(得分:0)
如果类型不会改变,要制作唯一键,您可以使用
String id = Arrays.toString(col1, col2, col3);
如果你需要它们是唯一的,即使混合和匹配类型,你可以使用生成二进制格式的序列化或
StringBuilder idsb = new StringBuilder();
for(Object o: arrayOfObjects)
idsb.append(o.getClass()).append(':').append(o).append(',');
String id = idsb.toString();
如果你有
Object col1 = "2012-04-19 12:13:46", col2 = "2012-05-02", col3 = "Andy";
String key = col1+"~"+col2+"~"+col3;
答案 1 :(得分:0)
您可以尝试基于哈希码的方法
public static UUID id(List<?> list) {
BigInteger prime = BigInteger.valueOf(31);
BigInteger value = BigInteger.valueOf(list.size());
for (Object element : list) {
value = value.multiply(prime).add(BigInteger.valueOf(element.hashCode()));
value = value.multiply(prime).add(BigInteger.valueOf(element.getClass().hashCode()));
}
return UUID.nameUUIDFromBytes(value.toByteArray());
}
虽然这并不能保证100%的唯一性。
答案 2 :(得分:0)
您无法为任何对象执行此操作,因为例如java.lang.Object没有值。对于可以通过值识别的那些,有一个解决方案虽然不简单:
创建
MessageDigest md = MessageDigest.getInstance("MD5");
遍历要创建ID的对象中的所有字段,将它们转换为字节(不知何故,在最坏的情况下(字段+“”)。getBytes())并使用这些字节更新摘要
md.update(fieldBytes);
md.update(new int[0]); we need separator to be safe
最后将您的ID设为BigInteger
BigInteger id = new BigInteger(1, md.digest());
您也可以将其转换为十六进制字符串
String hex = String.format("%032X", id)
它几乎是独一无二的。 MD5是16个字节。或者你可以使用SHA-1,它更强,它是20字节。