从值集合生成唯一ID

时间:2012-12-13 12:23:41

标签: java uniqueidentifier

我想了解如何从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可以是任何数据类型。

3 个答案:

答案 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字节。