Java Linkedhashmap равно индивидуальной реализации метода - PullRequest
1 голос
/ 17 июня 2020

Я пытаюсь реализовать свою собственную LinkedHashMap, используя стратегию цепочки для борьбы с коллизиями. Ниже фрагмент кода показывает, что я пробовал до сих пор.

CustomLinkedHashMap

public class CustomLinkedHashMap<K, V> {
    private Entry<K, V>[] table;
    private int capacity = 4;
    private Entry<K, V> header;
    private Entry<K, V> last;

    @SuppressWarnings("unchecked")
    public CustomLinkedHashMap() {
        table = new Entry[capacity];
    }


    @SuppressWarnings("unchecked")
    public boolean equals(Object that) {
        if (!(that instanceof CustomLinkedHashMap)) {
            return false;
        }

        CustomLinkedHashMap<K, V> other = (CustomLinkedHashMap<K, V>) that;

        // if lists are empty
        if (header == null) {
            return other.header == null;
        }

        if (!header.equals(other.header)) {
            return false;
        }

        // Just one element
        if (header == last) {
            return true;
        }

        if (!header.equals(other.last)) {
            return false;
        }

        Entry<K, V> thisNode = header;
        Entry<K, V> otherNode = other.header;

        while (thisNode.next != last) {
            thisNode = thisNode.next;
            otherNode = otherNode.next;
            if (!(thisNode.equals(otherNode))) {
                return false;
            }
        }
        return true;
    }

    public void put(K newKey, V data) {
        if (newKey == null)
            return;    //nulls not allowed

        int hash = hash(newKey);

        Entry<K, V> newEntry = new Entry<K, V>(newKey, data, null);
        maintainOrderAfterInsert(newEntry);
        if (table[hash] == null) {
            table[hash] = newEntry;
        } else {
            Entry<K, V> previous = null;
            Entry<K, V> current = table[hash];
            while (current != null) { // reached to the last entry of bucket.
                if (current.key.equals(newKey)) {
                    if (previous == null) {  //node has to be insert on first of bucket.
                        newEntry.next = current.next;
                        table[hash] = newEntry;
                        return;
                    } else {
                        newEntry.next = current.next;
                        previous.next = newEntry;
                        return;
                    }
                }
                previous = current;
                current = current.next;
            }
            previous.next = newEntry;
        }
    }

    public boolean isEmpty() {
        return header == null;
    }

    public void clear() {
        if (table != null && capacity > 0) {
            header = null;
            last = null;
            capacity = 0;
        }

    }

    public void printMap() {

        Entry<K, V> currentEntry = header;
        while (currentEntry != null) {
            System.out.print("{" + currentEntry.key + "=" + currentEntry.value + "}" + " ");
            currentEntry = currentEntry.after;
        }
    }

    private int hash(K key) {
        return Math.abs(key.hashCode()) % capacity;
    }


    static class Entry<K, V> {
        K key;
        V value;
        Entry<K, V> next;
        Entry<K, V> before, after;

        public Entry(K key, V value, Entry<K, V> next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }

        @SuppressWarnings("unchecked")
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object instanceof Entry) {
                Entry<K, V> e = (Entry<K, V>) object;
                if (Objects.equals(key, e.key) && Objects.equals(value, e.value)) {
                    return true;
                }
            }
            return false;
        }

    }
}

CustomLinkedHashMap класс Полная реализация здесь .

Что касается моей реализации, когда я попробуйте метод equals, он всегда возвращает мне false.

 CustomLinkedHashMap<Integer, String> lhm = new CustomLinkedHashMap<>();
 lhm.put(13, "John");
 lhm.put(3, "Holmes");
 lhm.put(19, "Jenifer");

 CustomLinkedHashMap<Integer, String> lhm2 = new CustomLinkedHashMap<>();
 lhm2.put(13, "John");
 lhm2.put(3, "Holmes");
 lhm2.put(19, "Jenifer");

System.out.println(lhm.equals(lhm2)); // Returns true when using java.util.LinkedHashMap

Любые предложения были бы полезны.

1 Ответ

1 голос
/ 17 июня 2020

Ваш equals для CustomLinkedHashMap слишком сложен. Все, что вам действительно нужно, это проверить записи (и их порядок):

@Override
public boolean equals(@Nullable Object thatObject) {
    if (!(thatObject instanceof CustomLinkedHashMap)) {
        return false;
    }
    CustomLinkedHashMap<?,?> thatMap =
        (CustomLinkedHashMap<?,?>) thatObject;
    return Arrays.equals(this.table, thatMap.table);
}

Вам также понадобится реализация solid для Entry, которая проверяет ключ и значение по отношению к другому:

@Override
public boolean equals(@Nullable Object thatObject) {
    if (!(thatObject instanceof Entry)) {
        return false;
    }
    Entry<?,?> thatEntry = (Entry<?,?>) thatObject;
    if (!Objects.equals(this.key, thatEntry.key)) {
         return false;
    }
    return Objects.equals(this.value, thatEntry.value));
}
...