2012-01-20 30 views
9

Ho creato un set vettoriale per evitare il thrashing del GC con allocazioni iterator e simili (ottieni un nuovo/libero per il riferimento impostato e l'iteratore dell'insieme per ogni attraversamento di valori o chiavi di un HashSet)come ottengo un ID univoco per oggetto in Java?

comunque il metodo Object.hashCode() è un ID univoco per oggetto. (fallirebbe per una versione a 64 bit?)

Ma in ogni caso è overridable e quindi non è garantito univoco, né univoco per istanza di oggetto.

Se voglio creare un "ObjectSet" come ottengo un ID univoco garantito per ogni istanza di un oggetto ??

Ho appena trovato questo: che risponde.

How to get the unique ID of an object which overrides hashCode()?

+0

La domanda non è chiara. Che cosa stai cercando di ottenere esattamente e perché ha bisogno di un ID univoco per oggetto? – Paolo

+1

La descrizione di ciò che stai cercando di fare è * davvero * vaga. Potresti dare più informazioni? Potrebbe esserci un modo migliore per raggiungere il tuo obiettivo più grande. –

+0

Ho visto questa risposta/ricerca che risponde a ciò che volevo. http: // StackOverflow.it/questions/909843/java-how-to-get-the-unique-id-of-an-object-which-overrides-hashcode – peterk

risposta

5

java.lang.System.identityHashCode(obj); lo farà per te, se davvero ne hai bisogno e capisci le ripercussioni. Ottiene l'hashcode dell'identità, anche se il metodo per fornire l'hashcode è stato sovrascritto.

+13

Anche se questo ha già qualche mese, va notato che 'System.identityHashCode (Object)' non ** deve essere distinto per oggetti distinti (come già affermato in altre risposte e commenti)! – siegi

+1

Soluzione fornita (con alcune spiegazioni e dettagli): http://stackoverflow.com/questions/909843/java-how-to-get-the-unique-id-of-an-object-which-overrides-hashcode – Benj

+0

identityHashCode() restituisce il risultato del metodo hashCode() definito in Object. nella javadoc per tale metodo si afferma: "Per quanto ragionevolmente pratico, il metodo hashCode definito dalla classe Object restituisce interi distinti per oggetti distinti (questo in genere viene implementato convertendo l'indirizzo interno dell'oggetto in un numero intero, ma questa tecnica di implementazione non è richiesta dal linguaggio di programmazione JavaTM.) " –

5

No, non è così che funziona hashCode(). Il valore restituito non deve essere univoco. Il contratto esatto è indicato nello documentation.

Inoltre,

presumibilmente il metodo Object.hashCode() è un ID univoco per oggetto

non è vero. Per citare la documentazione:

Per quanto è ragionevolmente possibile, il metodo hashCode definito dalla classe Object fa ritorno interi distinti per oggetti distinti.

+0

Lo so - è per questo che ho fatto la domanda. – peterk

3

Provare a superare il java GC suona come una prematura ottimizzazione per me.

Il GC è già regolato per gestire piccoli oggetti di breve durata. Se hai problemi di prestazioni con GC, dovresti help the GC, non ri-implementarlo (IMNSHO)

+1

Mi piacerebbe se un GC deterministico in tempo reale fosse disponibile come plug-in per macchine virtuali java generiche in cui potevo garantire che il GC avrebbe consumato più di 2 millisecondi in ciascun fotogramma di un ciclo di simulazione da 60 Hz. Riducendo le allocazioni e liberando riduce il numero inevitabile di bancarelle periodiche di GC. – peterk

32

La soluzione più semplice consiste nell'aggiungere un campo all'oggetto. Questa è la soluzione più rapida ed efficiente ed evita qualsiasi problema di oggetti che non possono essere ripuliti.

abstract Ided { 
    static final AtomicLong NEXT_ID = new AtomicLong(0); 
    final long id = NEXT_ID.getAndIncrement(); 

    public long getId() { 
     return id; 
    } 
} 

Se non è possibile modificare la classe, è possibile utilizzare un IdentityHashMap come @ glowcoder viene eliminato soluzione.

private static final Map<Object, Long> registry = new IdentityHashMap<Object, Long>(); 
private static long nextId = 0; 

public static long idFor(Object o) { 
    Long l = registry.get(o); 
    if (l == null) 
     registry.put(o, l = nextId++); 
    return l; 
} 

public static void remove(Object o) { 
    registry.remove(o); 
} 
+0

il codice sopra dove si aggiunge un campo all'oggetto garantisce un ID univoco per istanza creato di fronte agli oggetti creati da più thread contemporaneamente? – Geek

+0

@Geek Lo farà se usi un AtomicLong. –