比较器不适用于TreeSet中的对象类型

时间:2016-12-09 12:16:05

标签: java comparator treeset xtend

我正在尝试使用带有自定义TreeSet的{​​{1}}来清除列表中的重复对象。 对于此代码:

Comparator
  

控制台上的实际输出:[p1-> 1,p2-> 2,p3-> 3,p4-> 4,p1-> 1,p3-> 3]

     

控制台上的预期输出:[p1-> 1,p2-> 2,p3-> 3,p4-> 4]

为什么我在集合中再次获得class ASDF { int i Pass ref new(Pass p, int i) { this.ref = p this.i=i } public static def void main(String[] args) { val list = new TreeSet( new Comparator<ASDF> { override compare(ASDF obj1, ASDF obj2) { if (obj1.ref == obj2.ref && obj1.i == obj2.i) { return 0 } return 1 } } ) val a1 = new ASDF(new Pass("p1"), 1) val a2 = new ASDF(new Pass("p2"), 2) val a3 = new ASDF(new Pass("p3"), 3) val a4 = new ASDF(new Pass("p4"), 4) list.addAll( a1, a2, a3, a4 , a1, a2, a3, a4 , a1, a2, a3, a4 , a1, a2, a3, a4 ) println(list.map['''«ref.s»->«i»''']) } } class Pass { @Accessors String s new (String s) { this.s=s } } p1p3在哪里出错?

注意:这只是一个示例代码段。在我的“真实”代码中,我无法覆盖Comparatorequals

2 个答案:

答案 0 :(得分:4)

If you break contract of the Comparator, don't expect TreeSet to behave correctly.

Namely, here you failed to make the comparator symmetric:

Pass p1 = new Pass("p1");
Pass p2 = new Pass("p2");
compare(p1, p2); // returns 1
compare(p2, p1); // also returns 1 - not good

If you don't care (or cannot even define) about total ordering, you'd do much better with a properly defined hashCode() and equals() and a HashSet.

If you cannot override those (as you write), create a Key class that will hold the relevant attributes, define Key's hashCode() and equals() and use a HashMap<Key, Pass>. Alternatively, Key might be just a wrapper that holds a reference to Pass and derives it's hash code and equals info from Pass' fields.

答案 1 :(得分:1)

Your problem is that you violate the contract of Comparator which says that if compare(a, b) returns a positive integer, compare(b, a) has to return a negative integer. Besides other requirements like transitive comparings. In your implementation you either return 0 or 1 which does not follow this contract, so the TreeSet cannot work properly of course.