2010-02-01 21 views

Respuesta

50

Cómo es único no se necesita ser?

Si es único dentro de un proceso, puede usar un AtomicInteger y llamar al incrementAndGet() cada vez que necesite un nuevo valor.

+7

+1, estaba a punto de publicar lo mismo. – BalusC

+1

Aún mejor para cebar AtomicInteger con Integer.MIN_VALUE. Esto ayuda a depurar y te da más números para jugar. – reccles

+3

también necesita pensar sobre el desbordamiento. smth like 'if (curInt == Integer.MAX_INT)' restablecer atomicInteger –

1

Simplemente genere ID y verifique si ya está presente o no en su lista de ID generados.

8
int uniqueId = 0; 

int getUniqueId() 
{ 
    return uniqueId++; 
} 

Agregue synchronized si quiere que sea seguro para subprocesos.

+1

Podría querer agregar una excepción para cuando los enteros sean demasiado altos y se vuelque. También podría querer iniciar uniqueId en Integer.MinInt() (El método se llama algo así). – sixtyfootersdude

+1

Esto funcionará solo cuando el proceso se ejecuta para siempre sin detenerse. Para las aplicaciones reiniciadas, comenzará desde 0 cada vez. – talonx

+0

Bueno, uno podría pensar en usar un Long en vez de un Entero en primer lugar. –

2
+0

Eso no devuelve un número entero. El formato es hexstring, como '20e8f3d6-3f8d-475b-8c19-9619a78bbdc8'. – BalusC

+0

@BalusC: Esto es simplemente el resultado String del que está hablando. Internamente, un UUID es un valor de 128 bits y, por lo tanto, podría interpretarse como un número entero (aunque sea BigInteger). – Adamski

+1

Aún así, no cabe en un número entero. – BalusC

4

Es fácil si tiene alguna restricción.

Si tiene un hilo, solo usa uniqueID ++; Asegúrese de almacenar el uniqueID actual cuando salga.

Si tiene varios subprocesos, funciona un método synchronEniqueID sincronizado común (implementado de la misma manera que anteriormente).

El problema es cuando tienes muchas CPU, ya sea en un clúster o en una configuración distribuida como un juego de igual a igual.

En ese caso, generalmente puede combinar dos partes para formar un solo número. Por ejemplo, cada proceso que genera una ID única puede tener su propio número de identificación de 2 bytes asignado y luego combinarlo con un ID único ++. Algo como:

return (myID << 16) & uniqueID++ 

Puede ser complicado distribuir la parte "myID", pero hay algunas maneras. Puede obtener uno de una base de datos centralizada, solicitar una identificación única de un servidor centralizado, ...

Si tiene un Long en lugar de un Int, uno de los trucos más comunes es tomar el ID del dispositivo (UUID)) de ETH0, que se garantiza que es exclusivo de un servidor; luego solo agregue un número de serie.

1

Si realmente se quiere decir entero en lugar de int:

Integer id = new Integer(42); // will not == any other Integer 

Si quieres algo visible fuera de una JVM a otros procesos o para el usuario, persistente, o una serie de otras consideraciones, a continuación, hay otros enfoques , pero sin contexto, probablemente sea mejor utilizar la exclusividad incorporada de la identidad del objeto dentro de su sistema.

1

¿Lo necesita?

  • único entre dos JVM corriendo en al mismo tiempo.
  • único incluso si se reinicia el JVM .
  • thread-safe.
  • ¿soporte nulo? si no, use int o long.
+0

Bill K. dio una solución para el primer caso, es decir, qué se puede hacer si desea que el ID sea único entre 2 JVM. ¿Cuál es el enfoque correcto para garantizar que el ID sea único incluso después de reiniciar JVM? – user1071840

+0

Oh, solicitar un identificador único de una de las bases de datos centralizadas funcionará después de reiniciar también. – user1071840

1
import java.util.UUID; 

public class IdGenerator { 
    public static int generateUniqueId() {  
     UUID idOne = UUID.randomUUID(); 
     String str=""+idOne;   
     int uid=str.hashCode(); 
     String filterStr=""+uid; 
     str=filterStr.replaceAll("-", ""); 
     return Integer.parseInt(str); 
    } 

    // XXX: replace with java.util.UUID 

    public static void main(String[] args) { 
     for (int i = 0; i < 5; i++) { 
      System.out.println(generateUniqueId()); 
      //generateUniqueId(); 
     } 
    } 

} 

la esperanza que esto le ayuda.

+2

-1. Si bien un UUID sin duda proporcionará un valor único, no hay garantía de que esta garantía de exclusividad persista cuando tome su código hash. Puede elegir un número aleatorio entre Integer.MIN_VALUE e Integer.MAX_VALUE y esperar lo mejor. –

+0

No es así. UUID.randomUUID() usa un generador de números aleatorios criptográficamente fuerte, por lo que debería ser mejor que usar un generador de números pseudoaleatorios más débil. –

-2

único en cualquier momento:

int uniqueId = (int) (System.currentTimeMillis() & 0xfffffff); 
+0

En referencia a [esta respuesta] (http://stackoverflow.com/a/2979239/344480), 'System.currentTimeMillis()' no devuelve valores únicos. – Matthias

Cuestiones relacionadas