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

Problem Statement

I have two Collections of the same type of object that I want to compare. In this case, I want to compare them based on an attribute that does not factor into equals() for the Objects. In my example, I'm using ranked collections of Names for instance:

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 want to compare the two Collections to assert that, for position i in each Collection, the weightedRank of each Name at that position is the same value. I did some Googling but didn't find a suitable method in Commons Collections or any other API so I came up with the following:

public boolean comparatorEquals(Collection col1, Collection col2,

Comparator c)

{

if (col1 == null)

return col2 == null;

if (col2 == null)

return false;

if (col1.size() != col2.size())

return false;

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

while(i1.hasNext() && i2.hasNext()) {

if (c.compare(i1.next(), i2.next()) != 0) {

return false;

}

}

return true;

}

Question

Is there another way to do this? Did I miss an obvious method from Commons Collections?

Related

I also spotted this question on SO which is similar though in that case I'm thinking overriding equals() makes a little more sense.

Edit

Something very similar to this will be going into a release of Apache Commons Collections in the near future (at the time of this writing). See https://issues.apache.org/jira/browse/COLLECTIONS-446.

解决方案

I'm not sure this way is actually better, but it is "another way"...

Take your original two collections, and create new ones containing an Adapter for each base object. The Adapter should have .equals() and .hashCode() implemented as being based on Name.calculateWeightedRank(). Then you can use normal Collection equality to compare the collections of Adapters.

* Edit *

Using Eclipse's standard hashCode/equals generation for the Adapter. Your code would just call adaptCollection on each of your base collections, then List.equals() the two results.

public class Adapter {

public List adaptCollection(List names) {

List adapters = new ArrayList(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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值