我必须将用他的id标识的User添加到set中,并且在运行时,所有用户表单都必须按此id排序。
我已经创建了TreeSet添加了一些User对象,并尝试迭代它。
这是我的尝试:
//irrelevant code removed
TreeSet<User> userSet = new TreeSet<User>();
userSet.add(new User(2));
userSet.add(new User(1));
userSet.add(new User(3));
Iterator<User> iterator = userSet.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
我写了类User,其中一个是字段id,构造函数有id作为参数。
public class User {
private int id;
// irrelevant code removed
public User(int id) {
this.id = id;
}
// irrelevant code removed
public String toString() {
return id + "";
}
}
当我运行此代码时,我得到ClassCastException。
这是stacktrace:
Exception in thread "main" java.lang.ClassCastException: OrderedUsers$User cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1188)
at java.util.TreeMap.put(TreeMap.java:531)
at java.util.TreeSet.add(TreeSet.java:255)
at OrderedUsers.<init>(OrderedUsers.java:9)
at Main.main(Main.java:6)
我做错了什么?
答案 0 :(得分:4)
当您决定使用TreeSet时,您的方法正确,因为使用TreeSet可以获得有序输出。但...
请注意,如果使用TreeSet,由于TreeSet已排序,您必须实现Comparable
。
当您实施Comparable时,您将得到您期望的结果。
我建议您执行以下更改:
public class User implements Comparable<User> {
private int id;
// irrelevant code removed
public User(int id) {
this.id = id;
}
// irrelevant code removed
public String toString() {
return id + "";
}
@Override
public int compareTo(User u) {
return id - u.id;
}
}
答案 1 :(得分:2)
将自定义Comparator
传递给TreeSet
constructor或在模型类中实施Comparable
TreeSet
维护排序顺序,需要知道如何比较User
答案 2 :(得分:2)
TreeSet通过执行与二进制搜索树(实际上是红黑树)类似的现有对象来内部存储对象。因此,您需要在User中实现Comparable接口,或者为TreeSet提供自定义Comparator。
如果您不希望用户对象以排序顺序存储,我建议使用ArrayList。
方法1:
public class User implements Comparable<User>
{
public int compare(User u)
{
if( u == null)
return 1;
return id - u.id;
}
}
方法2:
public class CompareUsers implements Comparator<User>
{
public int compareTo(User a, User b)
{
if(a == null)
return -1;
if(b == null)
return 1;
return a.id - b.id;
}
}
// Create an instance of this comparator class and pass to the TreeSet
// during initialization.
TreeSet<User> userSet = new TreeSet<User>(new CompareUsers());
答案 3 :(得分:2)
以下是TreeMap.java 1188
的陈述:
return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
: comparator.compare((K)k1, (K)k2);
因此,如果comparator
为null
,那么它会尝试将集合成员转换为(Comparable)
。如果您的班级未实施Comparable
,则会导致您看到的ClassCastException
。仅当您调用提供comparator
的{{1}}构造函数时(或者如果您从已有比较器的另一个TreeMap
复制它),Comparator
才为非null。