Java:唯一的 10 位 ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18227787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: Unique 10 digit ID
提问by magodiez
I need to generate a unique 10 digit ID in Java. These are the restrictions for this ID:
我需要在 Java 中生成一个唯一的 10 位 ID。这些是此 ID 的限制:
- Only Numeric
- Maximum 10 digits
- Possible to create up to 10 different IDs per second
- Has to be unique (even if the application re-starts)
- Not possible to save a number in the Database
- As fast as possible NOT to add much lattency to the system
- 只有数字
- 最多 10 位数字
- 每秒最多可创建 10 个不同的 ID
- 必须是唯一的(即使应用程序重新启动)
- 无法在数据库中保存数字
- 尽可能快,不要给系统增加太多延迟
The best solution I found so far is the following:
到目前为止,我发现的最佳解决方案如下:
private static int inc = 0;
private static long getId(){
long id = Long.parseLong(String.valueOf(System.currentTimeMillis())
.substring(1,10)
.concat(String.valueOf(inc)));
inc = (inc+1)%10;
return id;
}
This solution has the following problems:
该解决方案存在以下问题:
- If for any reason there is a need to create more than 10 IDs per seccond, this solution won't work.
- In about 32 years this ID could be repeated (This is probably acceptable)
- 如果出于某种原因需要每秒创建 10 个以上的 ID,则此解决方案将不起作用。
- 大约 32 年后,这个 ID 可以重复(这可能是可以接受的)
Any other solution to create this ID?
创建此 ID 的任何其他解决方案?
Any other problem I haven't thought of with mine?
还有什么我没有想到的问题吗?
Thanks for your help,
谢谢你的帮助,
采纳答案by OldCurmudgeon
This is a small enhancement to yours but should be resilient.
这是对你的一个小改进,但应该是有弹性的。
private static final long LIMIT = 10000000000L;
private static long last = 0;
public static long getID() {
// 10 digits.
long id = System.currentTimeMillis() % LIMIT;
if ( id <= last ) {
id = (last + 1) % LIMIT;
}
return last = id;
}
As it is it should manage up to 1000 per second with a comparatively short cycle rate. To extend the cycle rate (but shorten the resolution) you could use (System.currentTimeMillis() / 10) % 10000000000L
or (System.currentTimeMillis() / 100) % 10000000000L
.
事实上,它应该以相对较短的周期率管理每秒 1000 次。要延长循环速率(但缩短分辨率),您可以使用(System.currentTimeMillis() / 10) % 10000000000L
或(System.currentTimeMillis() / 100) % 10000000000L
。
回答by Kris
This may be a crazy idea but its an idea :).
这可能是一个疯狂的想法,但它是一个想法:)。
- First generate UUID and get a string representation of it with
java.util.UUID.randomUUID().toString()
Second convert generated string to byte array (
byte[]
)Then convert it to long buffer:
java.nio.ByteBuffer.wrap( byte digest[] ).asLongBuffer().get()
Truncate to 10 digits
- 首先生成 UUID 并获取它的字符串表示形式
java.util.UUID.randomUUID().toString()
第二次将生成的字符串转换为字节数组 (
byte[]
)然后将其转换为长缓冲区:
java.nio.ByteBuffer.wrap( byte digest[] ).asLongBuffer().get()
截断为 10 位数字
Not sure about uniqueness of that approach tho, I know that you can rely on uniqueness of UUIDs but haven't checked how unique are they converted and truncated to 10 digits long number.
不确定这种方法的唯一性,我知道您可以依赖 UUID 的唯一性,但还没有检查它们转换和截断为 10 位数字的唯一性。
Example was taken from JavaRanch, maybe there is more.
示例取自JavaRanch,也许还有更多。
Edit:As you are limited to 10 digits maybe simple random generator would be enough for you, have a look into that quesion/answers on SO: Java: random long number in 0 <= x < n range
编辑:由于您仅限于 10 位数字,也许简单的随机生成器对您来说就足够了,请查看 SO 上的问题/答案:Java:0 <= x < n 范围内的随机长数
回答by Martin Podval
What means that it has to be unique? Even across more currently running instances? It break your implementation.
什么意味着它必须是独一无二的?甚至跨更多当前正在运行的实例?它破坏了你的实现。
If it must be unique across universe, the best solution is to use UUID as it's mathematically proven identifier generator as it generates unique value per universe. Less accurate number brings you collisions.
如果它必须在 Universe 中唯一,最好的解决方案是使用 UUID,因为它是经过数学验证的标识符生成器,因为它为每个 Universe 生成唯一值。不太准确的数字会给你带来碰撞。
When there is only one concurrent instance, you can take current time in millis and solve 10ms problem using incrementation. If you sacrifice proper number of last positions in the number you can get many number within one milliseconds. I would than define the precision - I mean how much unique numbers do you need per seconds. You will solve the issue without any persistence using this approach.
当只有一个并发实例时,您可以以毫秒为单位获取当前时间并使用增量解决10ms问题。如果您牺牲数字中最后位置的适当数量,您可以在一毫秒内获得许多数字。我会比定义精度 - 我的意思是你每秒需要多少唯一数字。使用此方法,您将无需任何持久性即可解决问题。
回答by abhineet
private static AtomicReference currentTime = new AtomicReference<>(System.currentTimeMillis());
private static AtomicReference currentTime = new AtomicReference<>(System.currentTimeMillis());
public static Long nextId() {
return currentTime.accumulateAndGet(System.currentTimeMillis(), (prev, next) -> next > prev ? next : prev + 1) % 10000000000L;
}