源码
List.equals源码
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof List)) {
return false;
}
final int expectedModCount = modCount;
// ArrayList can be subclassed and given arbitrary behavior, but we can
// still deal with the common case where o is ArrayList precisely
boolean equal = (o.getClass() == ArrayList.class)
? equalsArrayList((ArrayList<?>) o)
: equalsRange((List<?>) o, 0, size);
checkForComodification(expectedModCount);
return equal;
}
private boolean equalsArrayList(ArrayList<?> other) {
final int otherModCount = other.modCount;
final int s = size;
boolean equal;
if (equal = (s == other.size)) {
final Object[] otherEs = other.elementData;
final Object[] es = elementData;
if (s > es.length || s > otherEs.length) {
throw new ConcurrentModificationException();
}
for (int i = 0; i < s; i++) {
if (!Objects.equals(es[i], otherEs[i])) {
equal = false;
break;
}
}
}
other.checkForComodification(otherModCount);
return equal;
}
底层还是用Objects.equals、再往底层了说还是用list里元素的自己本身的equals方法进行比较的
Objects.equals(es[i], otherEs[i])
而且比较依赖元素的顺序
CollectionUtils.isEqualCollection源码
// 对于如下依赖的源码
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
public static boolean isEqualCollection(final Collection a, final Collection b) {
if(a.size() != b.size()) {
return false;
} else {
Map mapa = getCardinalityMap(a);
Map mapb = getCardinalityMap(b);
if(mapa.size() != mapb.size()) {
return false;
} else {
Iterator it = mapa.keySet().iterator();
while(it.hasNext()) {
Object obj = it.next();
if(getFreq(obj,mapa) != getFreq(obj,mapb)) {
return false;
}
}
return true;
}
}
}
public static Map getCardinalityMap(final 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;
}
public V get(Object key) {
Node<K,V> e;
return (e = getNode(key)) == null ? null : e.value;
}
private static final int getFreq(final Object obj, final Map freqMap) {
Integer count = (Integer) freqMap.get(obj);
if (count != null) {
return count.intValue();
}
return 0;
}
这个底层不是依赖equals、而是通过元素生成HashCode来比较、哪怕是个对象也会用这个对象去生成一个HashCode
hashMap的key的总数是一个比较点、这个相同说明不重复的元素个数相同
key相同的count又是一个比较点、这个相同说明重复的元素的个数相同
// 对于如下依赖的源码
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
待补充
Demo 举例
equals
ArrayList<String> listA = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
ArrayList<String> listB = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
System.out.println(listA.equals(listB)); // true
ArrayList<String> listA = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
ArrayList<String> listB = new ArrayList<>() {{
add("b");
add("a");
add("c");
}};
System.out.println(listA.equals(listB)); // false
ArrayList<String> listA = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
ArrayList<String> listB = new ArrayList<>() {{
add("a");
add("b");
}};
System.out.println(listA.equals(listB)); // false
ArrayList<String> listA = new ArrayList<>();
ArrayList<String> listB = new ArrayList<>();
System.out.println(listA.equals(listB)); // true
ArrayList<String> listA = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
System.out.println(listA.equals(null)); // false
结论:
1、顺序不同则视为不同
// 先排序再比较
Collections.sort(listA);
Collections.sort(listB);
System.out.println(listA.equals(listB));// true
CollectionUtils.isEqualCollection
ArrayList<String> listA = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
ArrayList<String> listB = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
System.out.println(CollectionUtils.isEqualCollection(listA, listB)); // true
ArrayList<String> listA = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
ArrayList<String> listB = new ArrayList<>() {{
add("c");
add("a");
add("b");
}};
System.out.println(CollectionUtils.isEqualCollection(listA, listB)); // true
ArrayList<String> listA = new ArrayList<>() {{
add("a");
add("b");
add("c");
}};
ArrayList<String> listB = new ArrayList<>() {{
add("a");
add("b");
}};
System.out.println(CollectionUtils.isEqualCollection(listA, listB)); // false
ArrayList<String> listA = new ArrayList<>();
ArrayList<String> listB = new ArrayList<>();
System.out.println(CollectionUtils.isEqualCollection(listA, listB)); //true
ArrayList<String> listA = new ArrayList<>();
System.out.println(CollectionUtils.isEqualCollection(listA, null));
java.lang.NullPointerException: Cannot invoke "java.util.Collection.size()" because "b" is null
结论:
1、比较会忽略顺序、只比较内容
2、不能比较null、报空指针