Compare whether two lists are equal (same element)
In a recent project, obtain and check whether the options in the two requests are the same, so I encountered the problem of checking whether the two lists are equal, so here I am yy.
Let's see how to compare two arrays to be equal. An array is a continuous memory space, so in general, two arrays are equal, that is, they have the same length, the same elements, and the same order. Let's take a look at the implementation of JDK Arrays. equals.
Public static boolean equals (int [] a, int [] a2) {if (a = a2) return true; if (a = null | a2 = null) return false; int length =. length; if (a2.length! = Length) return false; for (int I = 0; I
It is roughly divided into the following four steps:
1. Check whether it points to the same address (different references );
2. Non-empty check;
3. Check the length;
4. Check whether the order is equal to the corresponding element. (Compare in sequence. If one parameter is not equal, false is returned)
For List, there is no fixed order (the bottom layer of ArrayList is an array, you can use the array comparison method; but other lists, such as the sort List, are different .), Or order is not an important attribute for List. Therefore, you can consider other methods to check whether the two lists contain the same elements.
For example, JDK Collection. containsAll () only performs the contains () operation on each element. But the List allows repeated elements, so the number of repeated elements cannot be compared here:
public boolean containsAll(Collection
c) { for (Object e : c) if (!contains(e)) return false; return true; }
So how can we compare unordered elements with equal?
A simple and intuitive method is to sort the two lists separately and compare them one by one. If they are not equal, false is returned. If they are all equal, true is returned.
If (a. size ()! = B. size () return false; Collections. sort (a); Collections. sort (B); for (int I = 0; I
However, the efficiency of the two sorting operations is relatively low. So we can implement it through Map:
Saved firstHashMap, Key isElement, Value isNumber of occurrencesAnd then compare the number of occurrences of each element one by one. This ensures that all elements contain the same number of occurrences.
See org. apache. commons. collections. CollectionUtils. isEqualCollection () for details (). (The getCardinalityMap () feature is widely used in CollectionUtils)
Private static final Integer INTEGER_ONE = 1; public static boolean isw.collection (Collection a, Collection B) {if (a. size ()! = B. size () {// size is the simplest equal condition return false;} Map mapa = getCardinalityMap (a); Map mapb = getCardinalityMap (B); // After map conversion, can remove duplicates. In this case, size is a non-repeating item and is also a prerequisite for 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 first be available, and check the number of duplicates, that is, map. value if (getFreq (obj, mapa )! = GetFreq (obj, mapb) {return false ;}} return true ;}/ *** use obj as the key to prevent duplication, if the repeat operation is performed, the value ++ * actually records the elements and the number of occurrences */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 ;}