2014-09-15 2 views
2

Мне нужно создать класс, который имеет член int, который уникален для каждого объекта этого класса. Итак:Реализация класса с уникальным идентификационным номером

public class Cls { 
    private int id; 
    public Cls(){id = unique number;} 
} 

Так что, когда я делаю й количество Cls объектов, я должен быть уверен, что классы не имеют один и тот же идентификатор. Но я хочу избежать создания глобальной переменной в основном и установки идентификатора один за другим. Если это возможно, было бы здорово, если id можно установить в конструкторе.

ответ

5

Вы можете сохранить значение static, содержащее последнее значение, которое вы использовали, и всегда увеличивать его каждый раз, когда вы его используете. AtomicInteger отлично подходит для этого, потому что он потокобезопасен и не требует блокировок, если используется в многопоточной среде.

public class Cls { 
    // The last id I used. 
    private static final AtomicInteger nextId = new AtomicInteger(); 
    // My id 
    private final int id = nextId.getAndIncrement(); 

    public Cls() { 
    } 
} 
+0

Он вводит барьер памяти. – Basilevs

+0

@Basilevs - Да, это так - это то, что делает его потокобезопасным. – OldCurmudgeon

2

Используйте статическую переменную и увеличить его:

public class Cls { 

    private static int count = 0; 
    private int id; 

    public Cls() { 
     id = count; 
     count++; 
    } 
} 

Первый объект будет иметь id = 0, второй из них будет иметь id = 1 и т.д.

Ограничение: Этот метод является самым простым, но он не будет работать, если вы хотите иметь приложение, которое использует много потоков.


Многопоточность

Если вы находитесь в контексте многопоточности, вы должны быть уверены, что у вас есть какие-то ожидаемые результаты. Некоторые возможные методы:

1) Используйте класс из java.util.concurrent.atomic (например AtomicInteger) (в соответствии с OldCurmudgeon)

2) Вместо count++, вызвать синхронизированный метод, который имеет следующую структуру:

public static synchronized void incrementCount() { 
    count++; 
} 

3) используйте дополнительный объект для синхронизации:

private static final Object lock = new Object(); 

, а затем использовать его для синхронизации hronize операции инкремента:

public void increment() { 
    synchronized(lock) { 
     count++; 
    } 
} 
+2

Вы можете, но такой код не будет работать в многопоточной среде. Вам не гарантируется, что все экземпляры Cls имеют уникальные идентификаторы. – jarnbjo

+0

Я также добавил подробности о контексте многопоточности. Спасибо! –

0

Вы можете либо создать окружающую структуру, которая управляет уникальностью этого индекса или использовать UUID. UUID все еще имеет очень небольшую вероятность столкновения, но это не должно быть проблемой с небольшим количеством данных.

+0

Как вы бы описали "small"? – jarnbjo

+0

См. [Это] (http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates) для чисел – Dreizehn

+0

Я спросил, как * вы * определяете мелкие. – jarnbjo

0

Вы можете использовать UUID

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

UUID класс обеспечивает простое средство для генерации уникальных идентификаторов.

import java.util.UUID; 

public class GenerateUUID { 

    public static final void main(String... aArgs){ 
    UUID uniqueID = UUID.randomUUID(); 
    log("unique ID: " + uniqueID); 
    } 

    private static void log(Object aObject){ 
    System.out.println(String.valueOf(aObject)); 
    } 
} 

read more

0

ли это быть числовым? Кроме того, вы ищете уникальную версию jvm или уникальную во всех прогонах приложения? Вы ищете уникальную только для живых объектов или всего приложения?

Для ограниченного набора ответов (нет, только через jvm, только для живых объектов), проще всего использовать идентификатор объекта объекта. Но это не числовое и может быть использовано повторно после того, как объект умрет. Однако вы получаете бесплатную уникальную уникальность.

Смежные вопросы