如何在Java中检查LinkedHashMaps的相等性 - 还考虑了插入顺序?

Edw*_*ard 5 java equals linkedhashmap

我想检查Java中两个LinkedHashMaps的相等性.

equals()-方法位于AbstractMap和只检查并使用相同的密钥和值条目存在于比较列表.因此,不检查插入顺序:

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");
    }

  }

}
Run Code Online (Sandbox Code Playgroud)

如何检查两个比较列表的插入顺序是否相同?

Tho*_*mas 6

我可能不能超越equals()LinkedHashMap,但提供一个辅助方法,例如像这样(灵感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());
} 
Run Code Online (Sandbox Code Playgroud)

然后就像使用它一样if( linkedEquals(lhm1, lhm3) ).

编辑:

根据请求,另一种产生较低性能(由于多次不必要的迭代)但需要编写更少代码的方法是将条目集转换为列表并进行比较,例如:

if( new ArrayList<>(lhm1.entrySet()).equals(new ArrayList<>(lhm3.entrySet()) ) { ... }
Run Code Online (Sandbox Code Playgroud)