2013-12-26 1 views
0

Я экспериментирую с конструктором копирования для клонирования объектов транспортного средства. Я переопределяю метод toString() класса под названием Vehicle только ради презентации. Но клоны должны быть уникальными и полностью независимыми.Как обеспечить, чтобы хэш-код не равнялся другому объекту того же типа случайно

Является ли это гарантией того, что если я создам тысячи клонов объекта Vehicle, то все они будут уникальными при проверке друг на друга с использованием метода equals()? У меня создается впечатление, что каждый созданный объект гарантированно всегда имеет новый и уникальный хэш-код, который никогда не сравнялся бы с другим, когда я использую метод equals() для сравнения.

Редакция: Моего вопроса на самом деле, был бы с помощью равных по умолчанию() метод, чтобы сравнить мои клоны 100000 убедиться, что каждый из них в самом деле, уникальных и равно() всегда будет возвращать ложь ???

public class App { 

    public List<Vehicle> buildCar(String type, int hp) 
    { 
     List<Vehicle> vs = new ArrayList<Vehicle>(); 
     Vehicle vObject = new Vehicle(); 
     vObject.setHorsePower(hp); 
     vObject.setType(type); 

     Vehicle newV = new Vehicle(vObject); 
     vs.add(newV); 
     vs.add(vObject); 
     return vs; 
    } 

    public static void main(String args[]){ 
     App ap = new App(); 
     List<Vehicle> vehicles = new ArrayList<Vehicle>(); 

     vehicles.addAll(ap.buildCar("car",100)); 

     Vehicle v1 = vehicles.get(0); 
     Vehicle v2 = vehicles.get(1); 

     System.out.println(v1.equals(v2)); // prints false. 
       //System.out.println(v2.hashCode()); 

    } 
} 
+3

Хэш-код не должен быть уникальным, только «Насколько это практически целесообразно». –

+0

Значит, метод equals() по умолчанию использует hashcode для проверки равенства? Как я могу обеспечить, чтобы клоны были индивидуальными в моих проверках кода Java, используя такие методы, как equals()? –

+0

Прочитайте javadoc каждого метода. Ваш 'equals()' ('Указывает, является ли какой-либо другой объект равным« this one.') не должен использовать 'hashcode()' ('Возвращает значение хэш-кода для объекта. ') Внутри. –

ответ

1

Метод equals всегда будет отличать между равными (независимо от того, что это означает) и неравномерным с точностью 100%. Сравнение хэш-кодов гарантируется только «не равным», если несоответствие хэш-кодов - одинаковые хеш-коды не означает «равный», будет истинным.

Одно нерушимое правило для хэш-кодов состоит в том, что если два объекта возвращают true для «equal», то их хэш-коды должны совпадать.

1

Это не так. Функция hashCode() возвращает int. Поэтому при создании объектов 2^32 + 1 по крайней мере один хеш-код появится дважды.

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


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

Независимость и уникальность - это разные критерии.

Независимость означает просто, что объект и его клон не разделяют состояние. Поэтому, если (например) объекты Vehicle имеют изменяемые компоненты, вам необходимо убедиться, что ваш метод clone также клонирует компоненты.

Уникальность требуется дополнительная информация. В частности, это зависит от того, что вы используете в качестве своего «теста» для уникальности.

  • Если вы используете == в качестве теста на уникальность, то любой реализации clone, который создает новый объект будет удовлетворять требованию. (Нормальное ожидание clone является то, что он будет создать новый объект ...)

  • Если вы используете equals в качестве теста на уникальность, то это зависит от того, как вы определяете метод equals. Реализация по умолчанию equals использует ==. Если вы переопределите equals для тестирования на основе полей объекта, то, если вы хотите, чтобы клоны были уникальными (в соответствии с equals) вам нужно какое-то поле идентификатора, которое служит идентификатором объекта ... и организует, что ваш метод clone дает каждый клонирует новое значение идентификатора. (И это означает, что просто делегировать Object.clone() недостаточно.)


Мой вопрос на самом деле, было бы с помощью равных по умолчанию() метод, чтобы сравнить мои клоны 100000 убедиться, что каждый из них в самом деле, уникальный и Equals() всегда будет возвращать ложь?

Да ... для любой разумной реализации clone().

Реализация по умолчанию Java equals(Object) выполняет тот же тест, что и Java ==, и это даст вам только true, если оба операнда являются одной и той же ссылкой на объект.

+0

Итак, я не хочу создавать программное обеспечение на этом страшном предположении, которое у меня есть. Как я могу убедиться, что объекты, которые будут сгенерированы путем клонирования, на самом деле абсолютно независимы и уникальны? Я хочу проверить это в своем java-коде. –

+0

Ну, вы можете проверить ссылку, если хотите это сделать. Просто используйте '==' вместо 'equals (Object)'. Каждый объект имеет уникальную ссылку. – Sibbo

0

Если вы используете правильную реализацию clone, результатом является объект, отличный от оригинала (то есть original.clone() != original).

equals реализация объекта проверяет, идентичны ли объекты (возвращаемое значение такое же, как для ==), то есть оно не возвращает true для клона, если правильно выполнено clone(). В принципе вы можете думать о o.equals (o2) как проверку, если 2 объекта, переменные o и o2 ссылаются на одну и ту же память. (до сих пор говорят о том, что не-переоценка равна реализации)

Поэтому клоны и оригинал будут попарно разными, если вы проверите с равными.

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