I can not go through the TreeSet

I need to add the user identified by his identifier to the set and at runtime, all user forms that should be sorted by this identifier.

I created a TreeSet, added some user objects and tried to iterate through it.

Here is my attempt:

//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() + " "); } 

I wrote a User class, where one of the id and constructor fields has id as a parameter.

 public class User { private int id; // irrelevant code removed public User(int id) { this.id = id; } // irrelevant code removed public String toString() { return id + ""; } } 

When I run this code, I get a ClassCastException.

Here is the stack:

 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) 

What am I doing wrong?

+6
source share
4 answers

You are on the right track when you decide to use a TreeSet, because with a TreeSet you can get ordered output. But ... Please note that if you use TreeSet, then because of the TreeSet sorting, you must implement Comparable .

When you implement Comparable, you will get what you expect.

I suggest you make these changes:

 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; } } 
+4
source

Either pass the custom Comparator to the TreeSet constructor or implement Comparable in your model class

TreeSet supports sorted order and needs to know how User can compare

+2
source

The TreeSet internally saves the object, performing comparisons with existing binary-looking search trees (in fact, this is a Red-Black tree). Therefore, you need to implement the Comparable interface in User or provide a custom Comparator for the TreeSet.

If you do not want user objects to be stored in sorted order, I would recommend using an ArrayList.

Method 1:

  public class User implements Comparable<User> { public int compare(User u) { if( u == null) return 1; return id - u.id; } } 

Method 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()); 
+2
source

Here's the TreeMap.java 1188 statement:

  return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2) : comparator.compare((K)k1, (K)k2); 

So if comparator is null , then it will try to apply the given element to (Comparable) . If your class does not implement Comparable , it will raise the ClassCastException that you saw. comparator not null only if you call the TreeMap constructor that comparator provides (or if you copy it from another SortedMap that already has a comparator).

+2
source

All Articles