【问题标题】:How does Collections.unmodifiableCollection use equals method?Collections.unmodifiableCollection 如何使用 equals 方法?
【发布时间】:2019-02-08 04:05:32
【问题描述】:

unmodifiableCollection 方法(以及本节后面讨论的synchronizedCollection 和checkedCollection 方法)返回一个集合,其equals 方法不调用底层集合的equals 方法。相反,它继承了 Object 类的 equals 方法,该方法只是测试对象是否相同。如果您将一个集合或列表变成一个集合,您将无法再测试相同的内容。视图以这种方式运行是因为在层次结构的这个级别上没有很好地定义相等性测试。视图对 hashCode 方法的处理方式相同。但是,unmodifiableSet 和 unmodifiableList 方法使用底层集合的 equals 和 hashCode 方法。

这个片段来自书核心java,然后我写了一些代码来验证它:

package collection.view;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;


public class ColsOf {
    public static void main(String[] args) {

        List<TestEqual> list1=new ArrayList<>();
        TestEqual e1 = new TestEqual(5, 3);TestEqual e2 = new TestEqual(5, 3);
        System.out.println(e1==e2);System.out.println(e1.equals(e2));
        list1.add(e1);
        List<TestEqual> imutableList = Collections.unmodifiableList(list1);
        System.out.println(imutableList.contains(e2));
        Collection<TestEqual> imutableColl = Collections.unmodifiableCollection(list1);
        System.out.println(imutableColl.contains(e2));

    }

}

class TestEqual{
    int i;
    int j;
    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return i*100+j;
    }
    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        return this.hashCode()==obj.hashCode();
    }
    public TestEqual(int i, int j) {
        super();
        this.i = i;
        this.j = j;
    }

}

运行代码,结果为:

false
true
true
true

所以我可以看到e1==e2 是假的,但imutableColl.contains(e2) 是真的

如果immutableColl在我调用contains方法时检查内存位置而不检查内容,那么imutableColl.contains(e2)应该是假的,为什么是真的?

如果问题出在contains方法上,那么如何验证书中描述的点呢?

【问题讨论】:

  • 谁说包含?
  • @shmosel 我认为 contains 方法会使用 equal() 方法来评估对象。而我只知道这种方式是看集合 equals 方法是否不会调用底层集合的 equals 方法。

标签: java collections


【解决方案1】:

您从Collections.unmodifiableCollection() 的文档中提供的摘录是关于它返回的Collection 对象的equals() 方法,如

immutableColl.equals(anotherColl)

这与集合的contains() 方法无关,它遵守Collection.contains() 的约定,就像它应该的那样:

当且仅当此集合包含至少一个元素 e 满足 (o==null ? e==null : o.equals(e)) 时才返回 true。

这正是您报告的观察结果。还要注意,尽管ListSet 合约详细说明了实现的equals() 方法的行为方式,但Collections.equals() 的合约明确拒绝覆盖Object.equals() 的任何要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    • 2011-12-08
    • 1970-01-01
    相关资源
    最近更新 更多