使用Comparator比较两个Java集合而不是equals()

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

我有两个我想要比较的同一类型对象的集合。在这种情况下,我想根据不考虑equals()对象的属性来比较它们。在我的例子中,我使用了名称的排名集合:

public class Name {
    private String name;
    private int weightedRank;

    //getters & setters

    @Override
    public boolean equals(Object obj) {
        return this.name.equals(obj.name); //Naive implementation just to show
                                           //equals is based on the name field.
    }
}

我想比较两个集合来断言,对于i每个集合中的位置weightedRank,每个名称在该位置的值是相同的。我做了一些谷歌搜索,但没有找到一个合适的方法在Commons Collections或任何其他API,所以我想出了以下内容:

public <T> boolean comparatorEquals(Collection<T> col1, Collection<T> col2,
        Comparator<T> c)
{
    if (col1 == null)
        return col2 == null;
    if (col2 == null) 
        return false;

    if (col1.size() != col2.size())
        return false;

    Iterator<T> i1 = col1.iterator(), i2 = col2.iterator();

    while(i1.hasNext() && i2.hasNext()) {
        if (c.compare(i1.next(), i2.next()) != 0) {
            return false;
        }
    }

    return true;
}

有没有另一种方法来做到这一点?我错过了Commons Collections的一个明显的方法吗?

提问于
用户回答回答于

拿出原来的两个集合,并为每个基础对象创建一个包含适配器的新集合。适配器应该具有.equals().hashCode()基于的实现Name.calculateWeightedRank()。然后,您可以使用普通的Collection平等来比较适配器的集合。

使用Eclipse的标准hashCode / equals代Adapter。你的代码只会在你的每个基础集合上调用adaptCollection,然后调用两个结果的List.equals()。

public class Adapter {

    public List<Adapter> adaptCollection(List<Name> names) {
        List<Adapter> adapters = new ArrayList<Adapter>(names.size());

        for (Name name : names) {
            adapters.add(new Adapter(name));
        }

        return adapters;
    }


    private final int name;

    public Adapter(Name name) {
        this.name = name.getWeightedResult();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + name;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Adapter other = (Adapter) obj;
        if (name != other.name)
            return false;
        return true;
    }

}
用户回答回答于

使用equivance-wrapped对象的集合(请参阅Equivalence中wrap方法)与sharakan提出的基于Adapter的解决方案类似,但是等价实现将与适配器实现分离,从而使您可以轻松使用多个Equivalence条件。

扫码关注云+社区