Уникальный номер объекта java

icella / CurrentTimeId.java

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

/**
* The object creation time can be set to object’s identifier property.
* For this purpose, System.currentTimeMillis() can be used. However,
* two or more objects may be created in a single millisecond.
* In this case, these objects will have the same id which is unacceptable.
* One way to cope with this problem is to use System.nanoTime().
* Even if the nano time is the smallest interval we can use, it does not
* also guarantee the uniqueness. To provide unique time stamps,
* I got help from AtomicReference class as follows.
*/
import java . util . concurrent . atomic . AtomicReference ;
public class CurrentTimeId
private static AtomicReference < Long >currentTime =
new AtomicReference <>( System . currentTimeMillis ());
public static Long nextId ()
return currentTime . accumulateAndGet ( System . currentTimeMillis (),
( prev , next ) -> next > prev ? next : prev + 1 )
>
>
/**
* Note that accumulateAndGet method is available since Java 8.
* If you use earlier versions you can implement the following method.
*/
import java . util . concurrent . atomic . AtomicReference ;
public class CurrentTimeId
private static AtomicReference < Long >currentTime =
new AtomicReference <>( System . currentTimeMillis ());
public static Long nextId ()
Long prev ;
Long next = System . currentTimeMillis ();
do
prev = currentTime . get ();
next = next > prev ? next : prev + 1 ;
> while (! currentTime . compareAndSet ( prev , next ));
return next ;
>
>

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

/**
* The simplest way of id generation is to maintain an id counter.
* The counter is actually an integer (mostly a Java long) that is
* incremented at each generation.
*
* The IdCounter below, holds a counter and provides the synchronized
* nextId() method returning the next value of the counter.
* Synchronization is crucial to guard your counter against concurrent
* accesses in multithreaded applications.
*/
public class IdCounter
private static long counter = 0 ;
public static synchronized long nextId ()
return ++ counter ;
>
>
/**
* With Java 1.5+, a better way is using atomics like AtomicLong which
* are already thread-safe in nature. So, you don’t need an explicit synchronization.
*/
import java . util . concurrent . atomic . AtomicLong ;
public class AtomicIdCounter
private static AtomicLong counter = new AtomicLong ( 0 );
public static long nextId ()
return counter . incrementAndGet ();
>
>

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

/**
* Instances of java.rmi.server.UID class generates serializable identifiers
* which are unique on the host they are produced. The host must meet two conditions for uniqueness:
*
* Reboot time must be greater than 1 millisecond
* Its system clock is never set backward
* next class generates a different UID string at each nextUID() call (sample UID: -61bdd364:14a9f9c3782:-8000).
*/
import java . rmi . server . UID ;
public class UIDGenerator
public static String nextUID ()
return new UID (). toString ()
>
>

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

/**
* Our previous solution, UID, generates unique strings on the host.
* They are not globally unique. So, two JVM instances may produce same UIDs.
* If you need universally unique identifiers you can use java.util.
* UUID (Universally Unique IDentifier) class.
*
* The nextUUID() method below generates a different UUID (or GUID) string at
* each call (sample UUID: 251baa74-dc82-4e46-ae58-d7479c06eff5)
*/
import java . util . UUID ;
public class UUIDGenerator
public static String nextUUID ()
return UUID . randomUUID (). toString ();
>
>

Источник

Java создает уникальный идентификатор для каждого экземпляра объекта, используя методы экземпляра вместо методов класса / static

Совершенно новичок в этом, поэтому, надеюсь, у меня есть терминология в правом названии. Я пытаюсь выяснить, как создать метод экземпляра, который будет выполнять следующие действия: — возвращается идентификационный номер. — Как каждый объект создается из конструктора класса (созданного экземпляром?), ему присваивается уникальный идентификатор целочисленного идентификатора. Первый идентификационный номер равен 1, а при создании новых объектов будут назначены последовательные номера. Я могу найти примеры методов класса/статики, которые делают выше, но я не могу понять, как это сделать с помощью метода экземпляра. Моя попытка ниже:

class Coordinates < private int private float xCoordinate; private float yCoordinate; public Coordinates() < //Asks for input and assigns it to the two variables below Scanner keyboard = new Scanner(System.in); System.out.println("Please enter the X Coordinate followed by the return key"); xCoordinate = keyboard.nextDouble(); System.out.println("Please enter the Y Coordinate followed by the return key"); yCoordinate = keyboard.nextDouble(); iD++; >public getiD() < return iD; >> 

Обратите внимание: я не включил весь свой код ради простоты и простоты. Надеюсь, я добавил достаточно. Я также не хочу использовать java.util.UUID.

4 ответа

Проблема прямо сейчас в том, что ваш «id» является переменной экземпляра, то есть он принадлежит к созданным вами объектам. Подумайте, что каждый раз, когда вы создаете объект, создается новая и новая копия вашей переменной экземпляра. Поэтому каждый раз, когда вы создаете объект, идентификатор сначала устанавливается равным 0, затем пост увеличивается один раз (таким образом, все объекты имеют >

Если вы хотите создать переменную, которая, скажем, автоматически подсчитывает все объекты, созданные вами в классе или имеет идентификатор, вам нужно создать переменную класса. Эти переменные принадлежат всем объектам, созданным вами из класса, а ключевое слово, используемое для этого, — «статическое».

Примечание. Я использовал статическую переменную, но не статический метод. Если вы вообще не хотите использовать статику, это другой вопрос.

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

Вначале трудно понять концепцию класса и объектов, статические и переменные экземпляра. Дайте мне знать, если вы хотите получить больше объяснений:)

Отлично, легко следовать примеру. Единственное изменение, которое я сделал, было count, поэтому при создании экземпляра возражения значение count изменится на 1, а затем будет присвоено pointID. Это сделало бы так, чтобы идентификатор начинался с 1 вместо 0

Источник

Хэш-код объекта, hashCode

В классе Object, который является родительским классом для объектов java, определен метод hashCode(), позволяющий получить уникальный целый номер для данного объекта. Когда объект сохраняют в коллекции типа HashSet, то данный номер позволяет быстро определить его местонахождение в коллекции и извлечь. Функция hashCode() объекта Object возвращает целое число int, размер которого равен 4-м байтам и значение которого располагается в диапазоне от -2 147 483 648 до 2 147 483 647.

Рассмотрим простой пример HashCodeTest.java, который в консоли будет печатать значение hashCode.

public class HashCodeTest < public static void main(String[] args) < int hCode = (new Object()).hashCode(); System.out.println("hashCode = " + hCode); >>

Значение hashCode программы можно увидеть в консоли.

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

Функция сравнения объектов equals()

В родительском классе Object наряду с функцией hashCode() имеется еще и логическая функция equals(Object)/ Функция equals(Object) используется для проверки равенства двух объектов. Реализация данной функции по умолчанию просто проверяет по ссылкам два объекта на предмет их эквивалентности.

Рассмотрим пример сравнения двух однотипных объектов Test следующего вида :

class Test < int f1 = -1; int f2 = -1; public Test (final int f1, final int f2) < this.f1 = f1; this.f2 = f2; >public int getF1() < return this.f1; >public int getF2() < return this.f2; >>

Создадим 2 объекта типа Test с одинаковыми значениями и сравним объекты с использованием функции equals().

public class EqualsExample < public static void main(String[] args) < Test obj1 = new Test(11, 12); Test obj2 = new Test(11, 12); System.out.println("Объекты :\n\tobj1 = " + obj1 + "\n\tobj2 = " + obj2); System.out.println("hashCode объектов :" + "\n\tobj1.hashCode = " + obj1.hashCode() + "\n\tobj2.hashCode = " + obj2.hashCode()); System.out.println("Сравнение объектов :" + "\n\tobj1.equals(obj2) = " + obj1.equals(obj2)); >>

Результат выполнения программы будет выведен в консоль :

Объекты : obj1 = example.Test@780324ff obj2 = example.Test@16721ee7 hashCode объектов : obj1.hashCode = 2013471999 obj2.hashCode = 376577767 Сравнение объектов : obj1.equals(obj2) = false

Не трудно было догадаться, что результат сравнения двух объектов вернет «false». На самом деле, это не совсем верно, поскольку объекты идентичны и в real time application метод должен вернуть true. Чтобы достигнуть этого корректного поведения, необходимо переопределить метод equals() объекта Test.

@Override public boolean equals(Object obj)

Вот теперь функция сравнения equals() возвращает значение «true». Достаточно ли этого? Попробуем добавить объекты в коллекцию HashSet и посмотрим, сколько объектов будет в коллекции? Для этого в в метод main примера EqualsExample добавим следующие строки :

Set objects = new HashSet(); objects.add(obj1); objects.add(obj2); System.out.println("Коллекция :\n\t" + objects);

Однако в коллекции у нас два объекта.

Коллекция : [example.Test@780324ff, example.Test@16721ee7]

Поскольку Set содержит только уникальные объекты, то внутри HashSet должен быть только один экземпляр. Чтобы этого достичь, объекты должны возвращать одинаковый hashCode. То есть нам необходимо переопределить также функцию hashCode() вместе с equals().

@Override public int hashCode()

Вот теперь все будет корректно выполняться — для двух объектов с одинаковыми параметрами функция equals() вернет значение «true», и в коллекцию попадет только один объект. В консоль будет выведен следующий текст работы программы :

Объекты : obj1 = example.Test@696 obj2 = example.Test@696 hashCode объектов : obj1.hashCode = 1686 obj2.hashCode = 1686 Сравнение объектов : obj1.equals(obj2) = true Коллекция : [example.Test@696]

Таким образом, переопределяя методы hashCode() и equals() мы можем корректно управлять нашими объектами, не допуская их дублирования.

Использование библиотеки commons-lang.jar для переопределения hashCode() и equals()

Процесс формирования методов hashCode() и equals() в IDE Eclipse автоматизирован. Для создания данных методов необходимо правой клавишей мыши вызвать контекстное меню класса (кликнуть на классе) и выбрать пункт меню Source (Class >> Source), в результате которого будет открыто следующее окно со списком меню для класса.

Выбираем пункт меню «Generate hachCode() and equals()» и в класс будут добавлены соответствующие методы.

@Override public int hashCode() < final int prime = 31; int result = 1; result = prime * result + f1; result = prime * result + f2; return result; >@Override public boolean equals(Object obj)

Библиотека Apache Commons включает два вспомогательных класса HashCodeBuilder и EqualsBuilder для вызова методов hashCode() и equals(). Чтобы включить их в класс необходимо внести следующие изменения.

import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; . @Override public int hashCode() < final int prime = 31; return new HashCodeBuilder(getF1()%2 == 0 ? getF1() + 1 : getF1(), prime).toHashCode(); >@Override public boolean equals(Object obj)

Примечание : желательно в методах hashCode() и equals() не использовать ссылки на поля, заменяйте их геттерами. Это связано с тем, что в некоторых технологиях java поля загружаются при помощи отложенной загрузки (lazy load) и не доступны, пока не вызваны их геттеры.

Скачать пример

Исходный код рассмотренного примера в виде проекта Eclipse можно скачать здесь (263 Kб).

Источник

Читайте также:  Python plt figure figsize
Оцените статью