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

时间:2014-11-12 13:38:30

标签: java string algorithm hashcode uniqueidentifier

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

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

但它似乎效率很低,因为ID可以是一个字符串,但可能不包含&#34; - &#34;,所以它只包含数字,当它可能包含字母和Math.abs减半可能的数量标识。哦,ID必须长度相同(8个字母)。它只需要在地图和XML文件中作为密钥运行,而不必是安全的。

1 个答案:

答案 0 :(得分:1)

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

如果您的钥匙不必是安全的,那么计数器将是有效的并且保证唯一性。一个示例实现是生成由区分大小写的字母数字组成的ID,它会为您提供大约10 ^ 14个ID(您还可以添加特殊字符以增加ID的数量)。你需要一个62个字符的数组:索引0-25有小写字母,索引26-51有大写字母,索引52-61有数字。你还需要一个8个整数(或短路或字节)的状态数组,初始化为全0。要检索id,请使用state数组查找字符数组中的字符并将它们连接在一起(因此状态为{0,1,2,0,1,2,0,1}会生成id“abcabcab” );然后递增状态数组的第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,则它将第二个索引设置为0并递增第3个索引,同时,Worker_Thread已调用getBatchId,现在有一个状态数组的副本;它使用它生成id,之后它递增状态数组的第0个索引,如果这导致数字大于61,那么它将第0个索引设置为0并递增第1个索引,如果这导致数字更大然后它会调用getBatchId来获取新的状态数组。这意味着Worker_Thread实例只需要为每62 ^ 2个ID中的一个调用同步方法。

替代多线程实现将Id_Thread连续生成ID并将其放在BlockingQueue(最大队列大小为32)中,Worker_Thread实例从此队列中拉出id。