2013-08-14 31 views
9

Tôi cần tạo một ID gồm 10 chữ số duy nhất trong Java. Đây là những hạn chế đối với ID này:Java: ID có 10 chữ số duy nhất

  • Chỉ Số
  • tối đa 10 chữ số
  • Có thể tạo tối đa 10 ID khác nhau cho mỗi thứ hai
  • Có phải là duy nhất (ngay cả khi ứng dụng lại bắt đầu)
  • Không thể lưu một số trong cơ sở dữ liệu
  • càng nhanh càng tốt KHÔNG để thêm nhiều lattency với hệ thống

Giải pháp tốt nhất mà tôi tìm thấy cho đến nay như sau:

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; 
} 

Giải pháp này có những vấn đề sau đây:

  • Nếu vì lý do nào đó có nhu cầu để tạo ra hơn 10 ID mỗi seccond , giải pháp này sẽ không hoạt động.
  • Trong khoảng 32 năm ID này có thể được lặp đi lặp lại (Đây có lẽ là chấp nhận được)

Bất kỳ giải pháp khác để tạo ra ID này?

Bất kỳ vấn đề nào khác mà tôi chưa từng nghĩ đến với tôi?

Cảm ơn sự giúp đỡ của bạn,

+1

Có thể có nhiều trường hợp ứng dụng chạy cùng một lúc không? – assylias

+0

Chỉ một phiên bản đang chạy ngay bây giờ, nhưng có thể có trong tương lai. Chúng tôi cũng có một ví dụ seccondary trong trường hợp chính đi xuống, nhưng chỉ có một trong số họ (chính hoặc seccondary) sẽ chạy cùng một lúc. – magodiez

+0

Như đã chỉ ra trong một số câu trả lời dưới đây, việc triển khai của tôi sẽ thất bại trong môi trường đa môi trường hoặc đa luồng, vì vậy hãy giả định rằng một cá thể đơn lẻ với một chuỗi đơn lẻ sẽ chạy. – magodiez

Trả lời

7

Đây là một cải tiến nhỏ như của bạn nhưng nên được đàn hồi.

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; 
} 

Vì nó nên quản lý tối đa 1000 mỗi giây với tốc độ chu kỳ tương đối ngắn.Để mở rộng tốc độ chu kỳ (nhưng rút ngắn độ phân giải), bạn có thể sử dụng (System.currentTimeMillis()/10) % 10000000000L hoặc (System.currentTimeMillis()/100) % 10000000000L.

+1

Nó có lẽ là một ý tưởng tốt để làm cho nó thread-an toàn quá. – assylias

+0

Sử dụng (System.currentTimeMillis()/100) sẽ thực sự giải quyết được vấn đề nếu có thêm 10 ID phải được tạo trong cùng một seccond, vì điều này sẽ không bao giờ là một cái gì đó liên tục. Cảm ơn,;) – magodiez

+0

Hãy nhớ rằng 'System.currentTimeMillis()' có độ phân giải tối thiểu. Tôi đã tìm thấy nó bước khoảng 15ms trên hệ thống MS nên '/ 100' có thể không được mịn như bạn nghĩ, mặc dù thuật toán này sẽ đối phó với điều đó cho bạn. – OldCurmudgeon

2

Đây có thể là một ý tưởng điên rồ nhưng ý tưởng của nó :).

  • Đầu tiên tạo UUID và nhận được một chuỗi đại diện của nó với java.util.UUID.randomUUID().toString()
  • Second chuyển đổi chuỗi tạo ra để byte array (byte[])

  • Sau đó chuyển nó sang đệm dài: java.nio.ByteBuffer.wrap(byte digest[]).asLongBuffer().get()

  • Cắt ngắn thành 10 chữ số

Không chắc chắn về tính duy nhất của phương pháp tiếp cận đó, tôi biết rằng bạn có thể dựa vào tính độc đáo của UUID nhưng chưa kiểm tra mức độ độc đáo của chúng được chuyển đổi và cắt ngắn thành 10 chữ số dài.

Ví dụ được lấy từ JavaRanch, có thể có nhiều hơn.

Edit: Như bạn được giới hạn đến 10 chữ số phát ngẫu nhiên có lẽ đơn giản sẽ là đủ cho bạn, có một cái nhìn vào quesion rằng/câu trả lời về SO: Java: random long number in 0 <= x < n range

+0

[UUID không * được bảo đảm là duy nhất] (http://stackoverflow.com/questions/5728205/is-unique-id-generation-using-uuid-really-unique). Mặc dù xác suất nhận được hai UUID giống hệt nhau là rất nhỏ. – assylias

+1

Chính xác, nhưng như tôi đã viết 'bạn có thể dựa vào tính độc đáo của họ', không phải là họ là duy nhất :) – Kris

0

Điều gì có nghĩa là nó phải là duy nhất? Ngay cả trên nhiều trường hợp hiện đang chạy? Nó phá vỡ việc thực hiện của bạn.

Nếu nó phải là duy nhất trên vũ trụ, giải pháp tốt nhất là sử dụng UUID vì nó là trình tạo mã định danh đã được chứng minh toán học vì nó tạo ra giá trị duy nhất cho mỗi vũ trụ. Số ít chính xác hơn mang đến cho bạn những va chạm.

Khi chỉ có một trường hợp đồng thời, bạn có thể mất thời gian hiện tại tính bằng milis và giải quyết vấn đề 10ms bằng cách sử dụng tăng dần. Nếu bạn hy sinh số lượng vị trí cuối cùng thích hợp trong số bạn có thể nhận được nhiều số trong vòng một phần nghìn giây. Tôi sẽ xác định độ chính xác - ý tôi là bạn cần bao nhiêu số duy nhất mỗi giây. Bạn sẽ giải quyết vấn đề mà không cần bất kỳ sự kiên trì nào bằng cách sử dụng phương pháp này.

0

riêng tư AtomicReference currentTime = new AtomicReference <> (System.currentTimeMillis());

public static Long nextId() { 
    return currentTime.accumulateAndGet(System.currentTimeMillis(), (prev, next) -> next > prev ? next : prev + 1) % 10000000000L; 
} 
+0

Vui lòng chỉnh sửa câu trả lời của bạn để định dạng mã chính xác. Ngoài ra, hãy thêm một số giải thích – Garf365

Các vấn đề liên quan