问题陈述
我有两个要比较的相同类型对象的集合。在本例中,我希望基于一个不包含对象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中的一个显而易见的方法?
相关
我还在SO上发现了this question,虽然在这种情况下,我认为覆盖equals()
会更有意义一些。
编辑
与此非常类似的东西将在不久的将来(在撰写本文时)发布Apache Commons Collections。参见https://issues.apache.org/jira/browse/COLLECTIONS-446。
发布于 2013-02-27 02:45:28
您可以使用Guava Equivalence类来解耦“比较”和“等价”的概念。你仍然需要编写你的比较方法(AFAIK Guava没有它),它接受一个等价的子类而不是比较器,但至少你的代码不会那么混乱,你可以基于任何等价标准来比较你的集合。
使用等价包装对象的集合(参见wrap method in Equivalence)类似于sharakan提出的基于适配器的解决方案,但是等价实现将从适配器实现中解耦,从而允许您轻松地使用多个等价条件。
发布于 2015-07-27 17:21:49
您可以使用从版本4开始添加到CollectionUtils
中的新isEqualCollection
方法。该方法使用Equator
接口实现提供的外部比较机制。请检查这个javadoc:CollectionUtils.isEqualCollection(...)和Equator。
https://stackoverflow.com/questions/15094818
复制相似问题