Как Java сравнивает ключ, если это файловый объект?

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

HashMap<File, Long> hashMap = new HashMap<File, Long>();

Если файл (test.log) существует в моей HashMap (я добавил его), но файл (test.log) изменен или изменен позже; когда я выпущу замену, найдет ли он существующий соответствующий объект или изменится СОСТОЯНИЕ файла, что изменит характер объекта. Таким образом, я буду косвенно добавлять новую пару «ключ-значение».

hashMap.replace(file, newModifiedTime); 

person Dane Balia    schedule 07.02.2013    source источник
comment
Вы пробовали читать код File.equals()?   -  person Augusto    schedule 07.02.2013
comment
Нет, но судя по ответам, которые у меня должны были быть :)   -  person Dane Balia    schedule 07.02.2013


Ответы (5)


Из javadoc описание равного

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

person UmNyobe    schedule 07.02.2013

File проверяет .equals()/.hashCode() на имя файла, поэтому ваши ключи "безопасны".

Javadoc так говорит.

Примечание: если вы используете JDK 7 или более позднюю версию, сделайте себе одолжение: отбросьте File, используйте Files/Path.

Примечание 2: обратите внимание, что если вы находитесь в каталоге /foo, new File("bar") и new File("/foo/bar") не совпадают. Если вы хотите, чтобы имя файла было «полным», используйте .getCanonicalFile().

Но опять же, сделайте себе одолжение и используйте Files. Это на порядки лучше.

person fge    schedule 07.02.2013

То, что хранится, имеет ключ - это хеширование файла. На самом деле это не означает, что хэшируется весь объект. Только Path используется для генерации хеша объекта File.

При сохранении объекта в качестве ключа к хеш-таблице. Он будет внутренне вызывать .hashCode()

http://docs.oracle.com/javase/6/docs/api/java/io/File.html#hashCode()

Из документов.

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

person fmsf    schedule 07.02.2013

HashMap использует метод hashCode() своих ключей. И File.hashCode() делает это согласно документы:

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

Короче говоря, хэш вычисляется на основе имени пути, а не содержимого файла.

person Oliver Charlesworth    schedule 07.02.2013

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

Если вы хотите изменить это поведение, вам, вероятно, следует использовать TreeMap и реализовать свой собственный компаратор, который сравнивает содержимое файла, дату последнего изменения и т. д.

person AlexR    schedule 07.02.2013