I'd like to check the equality of two LinkedHashMaps in Java.
the equals()
-method is located in AbstractMap
and only checks if and entry with the same key and value is present in the compared list. Thus, the insertion order is not checked:
package com.stackoverflow.tests;
import java.util.LinkedHashMap;
public class LinkedHashMapEqualsTest {
public static void main(String[] args) {
LinkedHashMap<String, String> lhm1 = new LinkedHashMap<String, String>();
lhm1.put("A", "1");
lhm1.put("B", "2");
lhm1.put("C", "3");
LinkedHashMap<String, String> lhm2 = new LinkedHashMap<String, String>();
lhm2.put("A", "1");
lhm2.put("B", "2");
lhm2.put("C", "3");
LinkedHashMap<String, String> lhm3 = new LinkedHashMap<String, String>();
lhm3.put("A", "1");
lhm3.put("C", "3");
lhm3.put("B", "2");
LinkedHashMap<String, String> lhm4 = new LinkedHashMap<String, String>();
lhm4.put("A", "1");
lhm4.put("B", "2");
LinkedHashMap<String, String> lhm5 = new LinkedHashMap<String, String>();
lhm5.put("A", "2");
lhm5.put("B", "2");
lhm5.put("C", "3");
if(lhm1.equals(lhm1)) {
System.out.println("Positive control. - SUCCESS");
}
if(lhm1.equals(lhm2)) {
System.out.println("lhm1 does equal lhm2; as expected. - SUCCESS");
}
if(lhm1.equals(lhm3)) {
System.out.println("lhm1 does equal lhm3, although the insert-order is different.");
}
if(!lhm1.equals(lhm4)) {
System.out.println("Negative control 1. - SUCCESS");
}
if(!lhm1.equals(lhm5)) {
System.out.println("Negative control 2. - SUCCESS");
}
}
}
How can I check if also the insertion order is the same for both compared lists?
This class extends HashMap and maintains a linked list of the entries in the map, in the order in which they were inserted. This allows insertion-order iteration over the map. That is, when iterating a LinkedHashMap, the elements will be returned in the order in which they were inserted.
LinkedHashMap maintains the insertion order.
A LinkedHashMap cannot contain duplicate keys. LinkedHashMap can have null values and the null key. Unlike HashMap, the iteration order of the elements in a LinkedHashMap is predictable.
P.S HashMap does not guarantee insertion order.
I'd probably not override equals()
of LinkedHashMap
but provide a helper method, e.g. like this (inspired by AbstractList#equals(...)
):
public static <K, V> boolean linkedEquals( LinkedHashMap<K, V> left, LinkedHashMap<K, V> right) {
Iterator<Entry<K, V>> leftItr = left.entrySet().iterator();
Iterator<Entry<K, V>> rightItr = right.entrySet().iterator();
while ( leftItr.hasNext() && rightItr.hasNext()) {
Entry<K, V> leftEntry = leftItr.next();
Entry<K, V> rightEntry = rightItr.next();
//AbstractList does null checks here but for maps we can assume you never get null entries
if (! leftEntry.equals(rightEntry))
return false;
}
return !(leftItr.hasNext() || rightItr.hasNext());
}
Then you use it like if( linkedEquals(lhm1, lhm3) )
.
Edit:
As per request, another way which yields lower performance (due to multiple unnecessary iterations) but requires to write less code would be to convert the entry sets to lists and compare those, e.g. like this:
if( new ArrayList<>(lhm1.entrySet()).equals(new ArrayList<>(lhm3.entrySet()) ) { ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With