在使用Java的集合時,有些時候會需要比較兩個集合是否相等,自己寫方法其實也簡單,但是既然有了好的實現,就不要自己造輪子了,只要了解這個輪子是什么原理就好了。
public static boolean isEqualCollection(final Collection<?> a, final Collection<?> b)
傳入兩個Collection就可以了,我們常用的List或者Set,根據源碼發現:
這個方法比較的是集合中的元素以及元素的個數,不管是List或者是Set,不要求順序相同。
下面是一個例子,其中的源碼可能因為版本更迭與最新的不同,但是原理是一樣的:
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.collections4.CollectionUtils;
import org.junit.Test;
public class Test1 {
// CollectionUtils.isEqualCollection
/**
* isEqualCollection
*
* public static <E> boolean isEqualCollection(Collection<E> a, Collection<E> b) Returns true iff the given Collections contain exactly the same elements with exactly the same cardinalities.
* That is, iff the cardinality of e in a is equal to the cardinality of e in b, for each element e in a or b.
*
* Parameters:
* a - the first collection, must not be null
* b - the second collection, must not be null
* Returns:
* true iff the collections contain the same elements with the same cardinalities.
*
*/
@Test
public void test1() {
ArrayList<String> arr1 = new ArrayList<String>();
arr1.add("1");
arr1.add("2");
arr1.add("2");
arr1.add("3");
arr1.add("4");
arr1.add("5");
ArrayList<String> arr2 = new ArrayList<String>();
arr2.add("1");
arr2.add("1");
arr2.add("2");
arr2.add("3");
arr2.add("5");
arr2.add("4");
System.out.println(CollectionUtils.isEqualCollection(arr1, arr2));
// copy的源碼
System.out.println(isEqualCollection(arr1, arr2));
}
public static boolean isEqualCollection(Collection a, Collection b) {
if (a.size() != b.size())
return false;
Map mapa = getCardinalityMap(a);
Map mapb = getCardinalityMap(b);
if (mapa.size() != mapb.size())
return false;
for (Iterator it = mapa.keySet().iterator(); it.hasNext();) {
Object obj = it.next();
if (getFreq(obj, mapa) != getFreq(obj, mapb))
return false;
}
return true;
}
private static Integer INTEGER_ONE = new Integer(1);
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, new Integer(c.intValue() + 1));
}
return count;
}
private static final int getFreq(Object obj, Map freqMap) {
Integer count = (Integer) freqMap.get(obj);
if (count != null)
return count.intValue();
else
return 0;
}
}
