Java算法String-ID-生成分层父子

标签 java string algorithm hashcode uniqueidentifier

生成唯一 ID 并放入 Map<String, Entity> 中的好算法是什么?实体是可以包含其他实体的容器/文件夹类,而字符串是 ID?我认为在生成新实体时,它应该始终使用其父实体的 ID,所以现在我所做的是

(Math.abs((parentName+entityName).hashCode())).toString;

但它似乎效率很低,因为 ID 可以是字符串但可能不包含“-”,因此它只包含数字,而它也可能包含字母,而 Math.abs 将可能的 ID 数量减半。哦,ID 必须具有相同的长度(8 个字母)。它只需在 map 和 XML 文件中用作 key ,并且不必是安全的。

最佳答案

将父 ID 包含在子 ID 中似乎没有任何优势。这样做的一个潜在优势是通过父 ID 查找所有子代(即返回所有以 parent_id 开头的 ID),但是您正在散列连接的 ID 并且您有一个最大 ID 长度,这使得这种方法不可行。

如果您的 key 不必是安全的,那么计数器将是高效的并保证唯一性。一个示例实现是生成由区分大小写的字母数字组成的 ID,这将为您提供大约 10^14 个 ID(您还可以添加特殊字符以增加 ID 的数量)。您需要一个包含 62 个字符的数组:索引 0-25 为小写字母,索引 26-51 为大写字母,索引 52-61 为数字。您还需要一个由 8 个整数(或短整数或字节)组成的状态数组,初始化为全 0。要检索 id,请使用状态数组查找字符数组中的字符并将它们连接在一起(因此 {0, 1, 2, 0, 1, 2, 0, 1} 的状态生成“abcabcab”的 id );然后增加状态数组的第 0 个索引,如果这导致数字大于 61,则将第 0 个索引设置为 0 并增加状态数组的第 1 个索引,如果这导致数字大于 61,则设置第 1 个索引到 0 并增加状态数组的第二个索引等。

我建议您使用 StringBuilder连接子字符串,否则你会生成很多垃圾字符串。您也可以使用 StringBuilder 替换状态数组,使用 StringBuilder#replace 代替 int/short/byte 增量操作。


如果您的应用程序是多线程的,那么计数器可能会成为瓶颈。解决此问题的一种方法是为每个工作线程保留 62 或 62^2 个 ID,例如:ID_Thread 是具有 ID 生成器的线程,其 getBatchId 方法同步并返回状态数组的副本。 ID_Thread 递增状态数组的 2nd 索引(不是第 0 个索引),如果这导致数字大于 61,则它将第 2 个索引设置为 0 并递增第 3 个索引等。同时,Worker_Thread 调用了 getBatchId,现在有一个状态数组的副本;它使用它来生成 id,之后它递增状态数组的第 0 个索引,如果这导致数字大于 61,则它将第 0 个索引设置为 0 并递增第 1 个索引,如果这导致数字更大比 61 则调用 getBatchId 获取新的状态数组。这意味着 Worker_Thread 实例只需要为每 62^2 个 id 中的一个调用同步方法。

另一种多线程实现方式是 Id_Thread 不断生成 ID 并将它们放入 BlockingQueue(最大队列大小为 32),其中Worker_Thread 实例从该队列中提取 ID。

关于Java算法String-ID-生成分层父子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26888335/

相关文章:

python - Arduino Serial.write() 丢失数据

.net - 当 TextBox 为空时,数据绑定(bind)不会更新

php - 如何在数组组中找到最常见的 n 个元素

algorithm - 如何确定桶排序的平均和最坏情况空间复杂度

在大图中查找神经痛点 2 的算法

java - JTextfield 数组帮助

java - 将元素添加到 Java 中的预初始化列表

java - 检查用户是否已存在于 firebase 实时数据库中

java - jdbcTemplate.update 用于自动递增和唯一 ID 字段

javascript - 如何在 JavaScript 中使用正则表达式优雅地提取字符串?