Compares two Lists for equality (same elements)

  A project I did recently requires checking whether two Lists are equal. Let's see how to compare two arrays for equality. An array is a contiguous memory space, so in general, two arrays are equal, which means they have the same length, the same elements, and the same order. Let's take a look at the JDK's Arrays.equals() implementation to see at a glance.

public static boolean equals(int[] a, int[] a2) {
	if (a==a2) return true;
	if (a==null || a2==null) return false;
	int length = a.length;
	if (a2.length != length) return false;
	for (int i=0; i<length; i++)
		if (a[i] != a2[i]) return false;
	return true;
}

  It is roughly divided into the following 4 steps:

  a. Check if it points to the same address (different references);

  b. Non-empty check;

  c. Length check;

  d. Order and corresponding element equality checks. (Compare in turn, as long as one is not equal, return false)

  For List, there is no fixed order (the bottom layer of ArrayList is an array, and the comparison method of arrays can be used; but other Lists, such as LinkedList, are not the same.), or the order is not an important attribute for List. . So you can consider other ways to check whether two Lists contain the same elements.

  Such as JDK's Collection.containsAll(), it just performs the contains() operation on each element. But List allows duplicate elements, so the number of duplicate elements cannot be compared here:

public boolean containsAll(Collection<?> c) {
	for (Object e : c)
		if (!contains(e))
			return false;
	return true;
}

  So, how to equal compare unordered elements?

  A simpler and more intuitive method is to sort the two lists respectively, and then compare them one by one. As long as they are not equal, return false, and if they are all equal, return true.

if (a.size() !=b.size())
    return false;
Collections.sort(a);
Collections.sort(b);
for (int i = 0; i <a.size(); i++) {
    if(!a.get(i).equals(b.get(i)))
       return false;
}
return true;

  However, the efficiency of such two sorting is still relatively low. So it can be achieved through Map:

  First store the HashMap, the key is the element, the value is the number of occurrences, and then the number of occurrences is compared element by element, which ensures that the elements are included and the number of occurrences is the same.

  As shown in the following code, you can refer to org.apache.commons.collections.CollectionUtils.isEqualCollection() for details. (The feature of getCardinalityMap() is heavily used in CollectionUtils)

private static final Integer INTEGER_ONE = 1;
public static boolean isEqualCollection(Collection a, Collection b){
    if (a.size() !=b.size()) { // size is the simplest equality condition
       return false;
    }
    Map mapa = getCardinalityMap(a);
    Map mapb = getCardinalityMap(b);
   
    // After converting the map, duplicates can be removed. At this time, size is a non-duplicate item, which is also a prerequisite.
    if (mapa.size() !=mapb.size()) {  
       return false;
    }
    Iterator it =mapa.keySet().iterator();
    while (it.hasNext()) {
       Object obj = it.next();
       // To query the same obj, both sides must have it first, and the number of repetitions must be checked, which is map.value
       if (getFreq(obj,mapa) != getFreq(obj, mapb)) {
           return false;
       }
    }
    return true;
}
/**
 * Use obj as the key to prevent repetition, if repeated, value++
 * This actually records the element and the number of times it occurs
 */
public static Map getCardinalityMap(Collection coll) {
    Map count = new HashMap();
    for (Iterator it =coll.iterator(); it.hasNext();) {
       Object obj =it.next();
       Integer c =(Integer) count.get(obj);
       if (c == null)   
           count.put(obj, INTEGER_ONE);
       else {
           count.put(obj, newInteger(c.intValue() + 1));
       }
    }
    return count;
}
private static final int getFreq(Objectobj, Map freqMap) {
    Integer count =(Integer) freqMap.get(obj);
    if (count != null) {
       return count.intValue();
    }
    return 0;
}

 

Article source: http://blog.csdn.net/tiwerbao/article/details/42836305

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326254658&siteId=291194637