14

I'm a beginner in programming and I have two classes. First class is:

public class User implements Comparable<User>

with field int age, constructor and overrided method of interface Comparable:

 @Override
    public int compareTo(User user) {
        return user.age >= age ? -1 : 0;
    }

Second class is public class SortUser with a method to make a Set collection from a List:

public Set<User> sort(List<User> list) {
        Set<User> result = new TreeSet<>();
        for (User user : list) {
            result.add(user);
        }
        return result;
    }

It seems to me that all User objects in a Set should be sorted, but when I made a List with 3 User objects...

 User a = new User(1);
 User b = new User(2);
 User c = new User(3);
 List<User> list = new ArrayList<>();
 list.add(c);
 list.add(a);
 list.add(b);

(Now the list's order is: 312) ...and created a Set (TreeSet) from that list:

SortUser sortUser = new SortUser();
Set<User> set = sortUser.sort(list);

At the end I have a set with that order: 13, it means that only two objects are in the set. What is going wrong?

aLittleMind
  • 183
  • 2
  • 3
  • 12
  • 3
    I wouldn't sort it by adding it to a set. Just call `sort` on the list. – Carcigenicate Mar 17 '17 at 17:34
  • 1
    You can't have a sorted Set. Sets are unordered collections. A sort() method needs to either sort a List (or other ordered collection) in place, or return a List. – chrisdowney Mar 17 '17 at 17:39
  • 1
    @chrisdowney Well, technically you *can* have an ordered set. You just have to make sure that the specific implementation supports it. Its very possible to write an ordered set implementation. – Carcigenicate Mar 17 '17 at 17:56
  • compareTo must return -1, 0 +1 . good practice is to rethink hashCode() and equals() – Jacek Cz Mar 17 '17 at 18:09
  • 1
    @Carcigenicate is correct. Consider the standard java.util.TreeSet - https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html That's literally an ordered set implementation. – Michael Peacock Mar 17 '17 at 21:13
  • @Carcigenicate Yes, true, but missing the point - the method returns a Set so the calling code cannot assume it's ordered. – chrisdowney Mar 18 '17 at 00:45
  • @chrisdowney I'm just saving against "you can't have an ordered set". I believe that's a misleading comment. I agree with your point though. – Carcigenicate Mar 18 '17 at 01:07

6 Answers6

13

As I see you have wrong implementation of compare method. Could you update it to?

@Override
public int compareTo(User user) {
  return Integer.compare(age, user.age);
}
Roma Khomyshyn
  • 1,112
  • 6
  • 9
1

What you're doing with the TreeSet is unnecessary. I'm not sure they're guaranteed to have certain ordering when iterated.

Just replace your sort method with

Collections.sort(list)

And my guess as to why an element is being dropped is your compareTo method never returns a 1 in any case, so elements are always considered to be less than or equal to other elements, which is probably screwing with the TreeSet.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
1

Please follow below methodology

In case of string.

    public static Comparator<Employee> NameComparator = new Comparator<Employee>() {
    @Override
    public int compare(Employee e1, Employee e2) {
        return e1.getName().compareTo(e2.getName());
    }
};

In case of Integer values

public static Comparator<Employee> SalaryComparator = new Comparator<Employee>() {

    @Override
    public int compare(Employee e1, Employee e2) {
        return (int) (e1.getSalary() - e2.getSalary());
    }
};
Lova Chittumuri
  • 2,994
  • 1
  • 30
  • 33
  • It's not a good way, when there is a possibility of one of the argument being negative. However in case of salary, i suppose there are checks there which doesn't let the salary be negative. – bpjoshi Oct 16 '17 at 12:00
0

User class

 public class User implements Comparable<User>{
  int age;
  User(int age){age=age;}
  @Override
  public int compareTo(User user) {
    return this.age >= age ? -1 : 0;
  }
 }

prepare list

   User a = new User(1);
   User b = new User(2);
   User c = new User(3);
   List<User> list = new ArrayList<>();
  list.add(c);
  list.add(a);
  list.add(b);

for sorting

 Set<User> list1 = new TreeSet(list);
rathna
  • 1,055
  • 2
  • 11
  • 23
0
class Scratch {
    public static void main(String[] args) {
        List<User> list = new ArrayList<>();
        list.add(new User(3));
        list.add(new User(1));
        list.add(new User(2));
        Collections.sort(list);
        list.forEach(el -> System.out.println(el.age));
    }
}

class User implements Comparable<User> {
    int age;

    User(int age) {
        this.age = age;
    }

    @Override
    public int compareTo(User user) {
        return this.age >= user.age ? -1 : 0;
    }
}
0

You might want to try this:

@Override
public int compareTo(User user) {
  if (this == user){
     return 0;
  }
  if (user != null){
     return this.age.compareTo(user.getAge())
  }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
John Erbynn
  • 355
  • 1
  • 4
  • 14