【问题标题】:How do I create a unique ID in Java? [duplicate]如何在 Java 中创建唯一 ID? [复制]
【发布时间】:2010-11-26 06:14:21
【问题描述】:

我正在寻找在 Java 中将唯一 ID 创建为字符串的最佳方法。

感谢任何指导,谢谢。

我应该提到我正在使用 Java 5。

【问题讨论】:

标签: java uniqueidentifier


【解决方案1】:

创建一个UUID

String uniqueID = UUID.randomUUID().toString();

【讨论】:

  • 这并不是人类可读的全部...
  • @pjp:真正随机生成的 ID 通常不是人类可读的。使其可读性通常会使其更长,这反过来又会降低其可读性。
  • 我不知道他想要一个人类可读的唯一 ID ...这会大大增加难度
  • 另一个注意事项 - 如果您只需要应用程序唯一性,并且 AtomicInteger(如 Michael Borgwardt 所述)是一个更好的选择,但如果您需要全局唯一性,那么 UUID 是一个更好的选择。跨度>
  • 为什么我们不能使用System.currentTimeMillis来生成一个单调递增的序列并添加一些随机正整数盐?
【解决方案2】:

如果您想要简短的、人类可读的 ID,并且只需要它们在每次 JVM 运行时都是唯一的:

private static long idCounter = 0;

public static synchronized String createID()
{
    return String.valueOf(idCounter++);
}    

编辑: cmets 中建议的替代方案 - 这依赖于线程安全的底层“魔法”,但更具可扩展性且同样安全:

private static AtomicLong idCounter = new AtomicLong();

public static String createID()
{
    return String.valueOf(idCounter.getAndIncrement());
}

【讨论】:

  • 我更喜欢 Michael 的方法而不是 UUID 方法,因为在调试时顺序 ID 通常更有用/更容易。此外,UUID.randomUUID() 不能 100% 保证返回唯一值。
  • @Adamski:只要您不重新启动 JVM、仅运行 1 个 JVM 并且计数器不溢出,此方法只会创建唯一值。所有这些假设都很容易被打破。 UUID.randomUUID() 在这些情况下实际上更可靠。
  • 虽然不能保证 100%,但你与任何人发生碰撞的几率是如此之低(因为整个空间大于宇宙中估计存在的原子数量)以至于 100%保证。如果您需要全局唯一性,这是实现这一目标的最简单方法。但是,如果您只需要本地唯一性(即对于当前现有应用程序),那么 AtomicInteger 绝对是要走的路。
【解决方案3】:

java.util.UUID : toString() 方法

【讨论】:

    【解决方案4】:

    这是我的两分钱:我之前实现了一个IdFactory 类,它以 [主机名]-[应用程序开始时间]-[当前时间]-[鉴别器]格式创建 ID >。这在很大程度上保证了 ID 在 JVM 实例中是唯一的,同时保持 ID 的可读性(尽管很长)。这是代码以防万一:

    public class IdFactoryImpl implements IdFactory {
      private final String hostName;
      private final long creationTimeMillis;
      private long lastTimeMillis;
      private long discriminator;
    
      public IdFactoryImpl() throws UnknownHostException {
        this.hostName = InetAddress.getLocalHost().getHostAddress();
        this.creationTimeMillis = System.currentTimeMillis();
        this.lastTimeMillis = creationTimeMillis;
      }
    
      public synchronized Serializable createId() {
        String id;
        long now = System.currentTimeMillis();
    
        if (now == lastTimeMillis) {
          ++discriminator;
        } else {
          discriminator = 0;
        }
    
        // creationTimeMillis used to prevent multiple instances of the JVM
        // running on the same host returning clashing IDs.
        // The only way a clash could occur is if the applications started at
        // exactly the same time.
        id = String.format("%s-%d-%d-%d", hostName, creationTimeMillis, now, discriminator);
        lastTimeMillis = now;
    
        return id;
      }
    
      public static void main(String[] args) throws UnknownHostException {
        IdFactory fact = new IdFactoryImpl();
    
        for (int i=0; i<1000; ++i) {
          System.err.println(fact.createId());
        }
      }
    }
    

    【讨论】:

      【解决方案5】:

      使用 Java 生成唯一 ID

      UUID 是在 Java 中生成唯一 ID 的最快、最简单的方法。

      import java.util.UUID;
      
      public class UniqueIDTest {
        public static void main(String[] args) {
          UUID uniqueKey = UUID.randomUUID();
          System.out.println (uniqueKey);
        }
      }
      

      【讨论】:

        【解决方案6】:

        恕我直言,aperkins 提供了一个优雅的解决方案,因为它是原生的并且使用更少的代码。 但是如果您需要更短的 ID,您可以使用这种方法来减少生成的字符串长度:

        // usage: GenerateShortUUID.next();
        import java.util.UUID;
        
        public class GenerateShortUUID() {
        
          private GenerateShortUUID() { } // singleton
        
          public static String next() {
             UUID u = UUID.randomUUID();
             return toIDString(u.getMostSignificantBits()) + toIDString(u.getLeastSignificantBits());
          }
        
          private static String toIDString(long i) {
              char[] buf = new char[32];
              int z = 64; // 1 << 6;
              int cp = 32;
              long b = z - 1;
              do {
                  buf[--cp] = DIGITS66[(int)(i & b)];
                  i >>>= 6;
              } while (i != 0);
              return new String(buf, cp, (32-cp));
          }
        
         // array de 64+2 digitos 
         private final static char[] DIGITS66 = {
            '0','1','2','3','4','5','6','7','8','9',        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
            '-','.','_','~'
          };
        
        }
        

        【讨论】:

          【解决方案7】:

          这为 UUID 生成增加了一点随机性,但确保每个生成的 id 长度相同

          import org.apache.commons.codec.digest.DigestUtils;
          import java.util.UUID;
          
          public String createSalt() {
              String ts = String.valueOf(System.currentTimeMillis());
              String rand = UUID.randomUUID().toString();
              return DigestUtils.sha1Hex(ts + rand);
          }
          

          【讨论】:

          • 我喜欢额外的 currentTimeMillis,它确实使这个随机化。
          • UUID.randomUUID() 已经使用“加密强”随机数生成器生成 id。添加“更多随机性”是什么意思?根据纪元时间附加随机“盐”会得到什么?
          • 如果我没记错的话UUID.randomUUID() 在创建随机 ID 时已经使用了时间因素。
          【解决方案8】:

          我们可以使用UUID在java中创建一个唯一的ID,并在UUID上调用randomUUID()之类的方法。

          String uniqueID = UUID.randomUUID().toString();
          

          这将生成随机的uniqueID,其返回类型将为String

          【讨论】:

            【解决方案9】:

            java中生成唯一id的三种方式。

            1) UUID 类提供了一种生成唯一 ID 的简单方法。

             UUID id = UUID.randomUUID();
             System.out.println(id);
            

            2) SecureRandom 和 MessageDigest

            //initialization of the application
             SecureRandom prng = SecureRandom.getInstance("SHA1PRNG");
            
            //generate a random number
             String randomNum = new Integer(prng.nextInt()).toString();
            
            //get its digest
             MessageDigest sha = MessageDigest.getInstance("SHA-1");
             byte[] result =  sha.digest(randomNum.getBytes());
            
            System.out.println("Random number: " + randomNum);
            System.out.println("Message digest: " + new String(result));
            

            3) 使用 java.rmi.server.UID

            UID userId = new UID();
            System.out.println("userId: " + userId);
            

            【讨论】:

              【解决方案10】:

              带有计数信息的唯一 ID

              import java.util.concurrent.atomic.AtomicLong;
              
              public class RandomIdUtils {
              
                  private static AtomicLong atomicCounter = new AtomicLong();
              
                  public static String createId() {
              
                      String currentCounter = String.valueOf(atomicCounter.getAndIncrement());
                      String uniqueId = UUID.randomUUID().toString();
              
                      return uniqueId + "-" + currentCounter;
                  }
              }
              

              【讨论】:

                【解决方案11】:
                String name,password;
                
                public int idGen() {
                
                    int id = this.name.hashCode() + this.password.hashCode();
                    int length = String.valueOf(id).length();
                    int Max_Length = 5;
                    if(String.valueOf(id).length()>Max_Length) 
                    {
                        id = (int) (id /Math.pow(10.0,length - Max_Length ));
                    }
                    return  id;
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-08-26
                  • 2022-11-28
                  • 2021-06-20
                  • 2010-11-15
                  • 2016-08-21
                  相关资源
                  最近更新 更多