Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 比较器不';无法在树集中处理对象类型_Java_Comparator_Treeset_Xtend - Fatal编程技术网

Java 比较器不';无法在树集中处理对象类型

Java 比较器不';无法在树集中处理对象类型,java,comparator,treeset,xtend,Java,Comparator,Treeset,Xtend,我正试图借助一个带有自定义比较器的TreeSet来消除列表中的重复对象。 对于此代码: 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 Comp

我正试图借助一个带有自定义比较器的
TreeSet
来消除列表中的重复对象。 对于此代码:

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
    }
}
类ASDF{
int i
传球
新(通行证p,国际通行证i){
this.ref=p
这个。i=i
}
公共静态def void main(字符串[]args){
val list=新树集(
新比较器{
覆盖比较(ASDF obj1、ASDF obj2){
if(obj1.ref==obj2.ref&&obj1.i==obj2.i){
返回0
}
返回1
}
}
)
val a1=新ASDF(新通道(“p1”),1)
val a2=新ASDF(新通道(“p2”),2)
val a3=新ASDF(新通道(“p3”),3)
val a4=新ASDF(新通行证(“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»']
}
}
班级通行证{
@访问者
串
新的(字符串s){
这个.s=s
}
}
控制台上的实际输出:[p1->1,p2->2,p3->3,p4->4,p1->1,p3->3]

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

为什么我在集合中又得到了
p1
p3
?我在
比较器中哪里出错了


注意:这只是一个示例代码片段。在我的“真实”代码中,我无法覆盖
equals
hashcode
如果您违反
比较器的约定,请不要期望
树集
正常运行

也就是说,您未能使比较器对称:


如果您不关心(甚至不能定义)总排序,那么使用正确定义的
hashCode()
equals()
以及
HashSet
会做得更好


如果无法重写这些属性(在编写时),请创建一个包含相关属性的
Key
类,定义
Key
hashCode()
equals()
并使用
HashMap
。或者,
可能只是一个包装器,它保存了对
传递的引用,并从
传递
字段派生出它的哈希代码和相等信息。

如果您破坏了
比较器
的契约,请不要期望
树集
的行为正常

也就是说,您未能使比较器对称:


如果您不关心(甚至不能定义)总排序,那么使用正确定义的
hashCode()
equals()
以及
HashSet
会做得更好


如果无法重写这些属性(在编写时),请创建一个包含相关属性的
Key
类,定义
Key
hashCode()
equals()
并使用
HashMap
。或者,
Key
可能只是一个包装器,它保存了对
Pass
的引用,并从
Pass
字段中派生出它的哈希代码和相等信息。

您的问题是您违反了
Comparator
的约定,即如果
compare(a,b)
返回一个正整数,
compare(b,a)
必须返回一个负整数。除了其他要求,如传递性比较。在您的实现中,您返回的
0
1
不符合此约定,因此
TreeSet
当然不能正常工作。

您的问题是违反了
Comparator
的约定,即如果
compare(a,b)
返回一个正整数,
compare(b,a)
必须返回一个负整数。除了其他要求,如传递性比较。在您的实现中,您可以返回不符合此约定的
0
1
,因此
TreeSet
当然不能正常工作。

如何为
Pass
实现适当的equals方法,然后使用
obj1.ref.equals(obj2.ref)
而不是
obj1.ref==obj2.ref
。尝试过了。没有更改。为什么不发布一些可编译的代码。
obj1.ref==obj2.ref
。尝试
.equals()
。对于
Pass
如何实现适当的equals方法,然后使用
obj1.ref.equals(obj2.ref)
而不是
obj1.ref==obj2.ref
。尝试过了。没有更改。为什么不发布一些可编译的代码。
obj1.ref==obj2.ref
。试试
.equals()
。奇怪的是,OP并没有破坏传递性,因为他总是为不同的元素返回1,所以
aa
保持不变。我知道,我刚才提到了它,所以他在重新实现比较器时会考虑到它。:-)奇怪的是,OP并没有破坏传递性,因为他总是为不同的元素返回1,所以
aa
成立。我知道,我刚才提到了它,所以他在重新实现比较器时考虑了它。:-)
Pass p1 = new Pass("p1");
Pass p2 = new Pass("p2");
compare(p1, p2); // returns 1
compare(p2, p1); // also returns 1 - not good