2

我想了解如何从 Java 对象的集合中生成唯一 ID(字符串/数字等),这些对象可能是各种数据类型,如 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 可以是任何数据类型。

4

3 回答 3

0

您不能对任何对象执行此操作,因为例如 java.lang.Object 没有值。对于那些可以通过值来识别的,有一个解决方案虽然并不简单:

创造

MessageDigest md = MessageDigest.getInstance("MD5");

遍历要在其上创建 ID 的对象中的所有字段,将它们转换为字节(不知何故,在最坏的情况下为 (field + "").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 字节。

于 2012-12-13T12:53:25.603 回答
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% 的唯一性。

于 2012-12-13T12:53:11.890 回答
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;
于 2012-12-13T12:30:17.687 回答