Есть структура(класс).
public class Node {
private static String separator = "\\";
private Map<String, Node> fileMap = new HashMap<>();
private Node parent;
private String absolutePath;
private Integer hash;
public void addFile(File file) {
fileMap.put(file.getAbsolutePath(), new Node(file.getAbsolutePath(), this));
hash = hashCode();
}
public Node(String absolutePath, Node parent) {
this.absolutePath = absolutePath;
this.parent = parent;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Node)) return false;
Node node = (Node) o;
if (getFileMap() != null ? !getFileMap().equals(node.getFileMap()) : node.getFileMap() != null) return false;
return getAbsolutePath().equals(node.getAbsolutePath());
}
@Override
public int hashCode() {
boolean eq = getFileMap() != null;
int result;
if (eq){
result = getFileMap().hashCode();
result += 0;
} else
result = 0;
result = 31 * result + getAbsolutePath().hashCode();
return result;
}
Данная структура используется для представление иерархии файловой системы. То есть node может содержать сам файл, так и hashTable (fileMap) с вложенными файлами, если это директория, также файлы в hashTable (fileMap) могут быть файлами или директориями.
Специально переопределил метод hashCode() через if для наглядности.
Строка result = getFileMap().hashCode();
всегда возвращает 0, сколько бы разных сущностей в ней не было.
В итоге hash считается только от параметра "absolutePath". Что меня не устраивает, ведь мне нужно, чтобы хэш был разным в зависимости от вложенных файлов.
Иначе получается ситуация в которой, два дерева представляющих файловую систему, например:
testdir/innerdir/1/2
testdir/outdir
и содержащие одинаковую папку в root - "testdir" равны, т.к. хэш вложенных структур в hashTable не учитывается. Может кто-нибудь сказать Почему так происходит?
Если посмотреть в исходный код HashMap
(точнее его родителя AbstractMap
),то можно увидеть как реализовано метод hashCode()
.Он суммирует хеш коды всех элементов:
public int hashCode(){
int h=0;
Iterator<Entry<K, V>>i=entrySet().iterator();
while(i.hasNext())
h+=i.next().hashCode();
return h;
}
Далее смотрим как реализуют этот метод элементы HashMap
- HashMapEntry
:
public final int hashCode() {
return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
}
Здесь используется исключающее ИЛИ для хешкодов ключа и значения. То есть, если хешкоды ключа и значение будут равны, то метод вернёт 0.
В итоге получаем, что когда getFileMap() == null
, то для этого Node хешкод берётся от getAbsolutePath()
. Этот же getAbsolutePath()
является ключём в мапе, получается, что хешкоды ключа и значения равны, отсюда и возвращается 0.
Виртуальный выделенный сервер (VDS) становится отличным выбором
help me пожалуйста я очень долго мучаюсь помогите кто знает
Вопрос общего характера - как найти утечку памяти? Есть ли какие нибудь хорошие гайды? Можно на английскомБиблиотеку leack canary не советуйте,...