java TreeSet:比较和相等 [英] java TreeSet: comparing and equality
问题描述
我想用属性"sort_1"对对象列表进行排序.但是,当我想要删除时,我希望它使用属性"id".以下代码代表了问题.
I'd like to have list of object sorted with property 'sort_1'. But when I want to remove I'd like it to use property 'id'. The following code represents the problem.
package javaapplication1;
import java.util.TreeSet;
public class MyObj implements Comparable<MyObj> {
public long sort_1;
public long id;
public MyObj(long sort, long id) {
this.sort_1=sort;
this.id=id;
}
@Override
public int compareTo(MyObj other) {
int ret = Long.compare(sort_1, other.sort_1);
return ret;
}
public String toString() {
return id+":"+sort_1;
}
public static void main(String[] args) {
TreeSet<MyObj> lst=new TreeSet<MyObj>();
MyObj o1 = new MyObj(99,1);
MyObj o2 = new MyObj(11,9);
lst.add(o1);
lst.add(o2);
System.out.println(lst);
MyObj o3 = new MyObj(1234, 1);
//remove myObje with id 1
boolean remove=lst.remove(o3);
System.out.println(lst);
}
}
此代码的输出是:
[9:11, 1:99]
[9:11, 1:99]
我需要对列表进行排序,因为我对列表做了很多添加.我不想明确使用任何排序"方法.我有什么选择?
I need to have list sorted as I do a lot of additions to the list. I don't want to explicitly use any 'sort' method. What are my options ?
我的要求是:具有"id"的对象是唯一的,但是可以存在具有重复"sort"值的对象.
My requirement is to have: objects with 'id' as unique but there can be object's with duplicate 'sort' value.
推荐答案
I think the problem you're having is that you are implementing Comparable, but your implementation seems to be inconsistent with equals - and you have not implemented any equality methods. That is:
当且仅当e1.compareTo(e2)== 0具有与e1.equals(e2)相同的布尔值(对于C类的每个e1和e2)时,类C的自然顺序才与equals一致.
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C
在您的情况下,当您构建这三个对象时:
In your case, when you build these three objects:
MyObj o1 = new MyObj(99,1);
MyObj o2 = new MyObj(11,9);
MyObj o3 = new MyObj(1234, 1);
您会看到o1.compareTo(o3)== -1,而o1.equals(o3)== false.
You will see that o1.compareTo(o3) == -1, while o1.equals(o3) == false.
但是您似乎想要o1.equals(o3)== true.
But you seem to want o1.equals(o3) == true.
此外,请注意,如果对象已经存在于集合中,则TreeSet.add()返回false.此检查基于equals()方法.
Also, recognize that TreeSet.add() returns false if the object already exists in the set. This check is based on the equals() method.
要解决此问题,请重写Object.equals()和Object.hashCode(),使它们考虑MyObj.id字段,并在不相等时继续在compareTo()方法中使用sort_1字段.
To remedy this, override Object.equals() and Object.hashCode() such that they take into consideration the MyObj.id field, and continue to use the sort_1 field in the compareTo() method when they are not equal.
package javaapplication1;
import java.util.TreeSet;
public class MyObj implements Comparable<MyObj> {
public long sort_1;
public long id;
public MyObj(long sort, long id) {
this.sort_1 = sort;
this.id = id;
}
@Override
public int compareTo(MyObj other) {
return (this.equals(other))? 0 : Long.compare(sort_1, other.sort_1);
}
@Override
public boolean equals(Object obj) {
MyObj other = (MyObj) obj;
return this.id == other.id && this.sort_1 == other.sort_1;
}
@Override
public int hashCode() {
return (int) id;
}
public String toString() {
return id + ":" + sort_1;
}
public static void main(String[] args) {
TreeSet<MyObj> lst = new TreeSet<MyObj>();
MyObj o1 = new MyObj(99L, 1L);
MyObj o2 = new MyObj(11L, 9L);
MyObj o3 = new MyObj(1234L, 1L);
MyObj o4 = new MyObj(1234L, 1L);
System.out.println( "Adding o1: " + lst.add(o1));
System.out.println( "Adding o2: " + lst.add(o2));
System.out.println( "Adding o3: " + lst.add(o3));
System.out.println( "Adding o4: " + lst.add(o4));
System.out.println(lst);
System.out.println("o1.compareTo(o3) : " + o1.compareTo(o3));
System.out.println("o1.equals(o3) : " + o1.equals(o3));
//remove myObje with id 1
boolean remove = lst.remove(o3);
System.out.println(lst);
}
}
输出:
Adding o1: true
Adding o2: true
Adding o3: true
Adding o4: false
[9:11, 1:99, 1:1234]
o1.compareTo(o3) : -1
o1.equals(o3) : false
[9:11, 1:99]
这篇关于java TreeSet:比较和相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!