Java linkedhashmap equals 方法自定义实现

Java Linkedhashmap equals method custom implementation

我正在尝试使用链接策略来实现我自己的 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 class 完全实施 here.

至于我的实现,当我尝试 equals 方法时,它总是 returns 我 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

如有任何建议,我们将不胜感激。

你的 equals for 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);
}

您还需要 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));
}