In TreeSet, sorting and uniqueness of custom objects based on different properties

Below is my class of students

class Student implements Comparable { String name; int rollNo; @Override public int compareTo(Object obj) { return ((Student)obj).name.compareTo(this.name); } } 

last modification: but still not getting the correct result

 @Override public int compareTo(Object obj) { Student s = (Student) obj; if (name.equals(s.name)) { // achieving uniqueness return 0; } else { if (rollNo < s.rollNo) { return -1; } else if (rollNo > s.rollNo) { return 1; } else { // this makes `name` the second ordering option. // names don't equal here return name.compareTo(s.name); } } } 

If I create a TreeSet <Student> object, I get a sorted list of Student objects based on a unique name and also sorted by name.

But I need a unique student name in my TreeSet <Student> with order student roll No..

Is this possible with a comparator? Can someone help me, every suggestion is welcome. Thank.

UPDATE: here is the complete program:

 public class Student implements Comparable { int rollNo; String name; Student(String n,int rno) { rollNo=rno; name=n; } /** * @param args */ public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>(); ts.add(new Student("bbb",2)); ts.add(new Student("aaa",4)); ts.add(new Student("bbb",2)); ts.add(new Student("ccc",3)); ts.add(new Student("aaa",1)); ts.add(new Student("bbb",2)); ts.add(new Student("bbb",5)); System.out.println(ts); } @Override public int compareTo(Object obj) { Student s = (Student) obj; if (name.equals(s.name)) { // achieving uniqueness return 0; } else { if (rollNo < s.rollNo) { return -1; } else if (rollNo > s.rollNo) { return 1; } else { // this makes `name` the second ordering option. // names don't equal here return name.compareTo(s.name); } } } @Override public String toString() { return name + rollNo; } } 

Update: 2: Thank you all for your suggestions, I still need more :)

 /* * Actual scenario is having different properties, * So here I am just relating my actual scenario with Student class */ class Student implements Comparable { // sorting required on rollNo int rollNo; // Unique name is required String name; Student(String n, int rno) { rollNo = rno; name = n; } /** * * @param args */ public static void main(String[] args) { TreeSet<Student> tsName = new TreeSet<Student>(); // here by default, order & uniqueness by name only tsName.add(new Student("ccc", 2)); tsName.add(new Student("aaa", 4)); tsName.add(new Student("ddd", 1)); tsName.add(new Student("bbb", 3)); tsName.add(new Student("ddd", 5)); // output: aaa:4, bbb:3, ccc:2, ddd:1 System.out.println(tsName); // creating new comparator for student RollNo TreeSet<Student> tsRollNo = new TreeSet<Student>(new Comparator<Student>() { public int compare(Student stud1, Student stud2) { return new Integer(stud1.rollNo).compareTo(stud2.rollNo); } }); tsRollNo.addAll(tsName); System.out.println(tsRollNo); // now got the desire output: ddd:1, ccc:2, bbb:3, aaa:4 } public boolean equals(Object obj) { // internally not used to check equality while adding objects // in TreeSet System.out.println("equals() for " + this + " & " + ((Student) obj)); return false;// return false/true doesn't make any sense here } @Override public int compareTo(Object obj) { Student s = (Student) obj; // internally inside TreeSet, compareTo is used to decide // whether two objects are equal or not, // ie compareTo will return 0 for same object(here student name) System.out.println("compareTo() for " + this + " & " + ((Student) obj)); // achieving uniqueness return name.compareTo(s.name); } @Override public String toString() { return name + ":" + rollNo; } } 

OUTPUT

 compareTo() for aaa:4 & ccc:2 compareTo() for ddd:1 & ccc:2 compareTo() for bbb:3 & ccc:2 compareTo() for bbb:3 & aaa:4 compareTo() for ddd:5 & ccc:2 compareTo() for ddd:5 & ddd:1 [aaa:4, bbb:3, ccc:2, ddd:1] [ddd:1, ccc:2, bbb:3, aaa:4] 

Friends, no matter what I get using two comparators, is it possible to achieve the same when adding objects? I cannot add the elements first and then use the new comparator to achieve the desired order.
I manipulate thousands of values, so productivity must be considered.

+8
java collections sorting unique treeset
Dec 15 2018-10-15T00:
source share
4 answers

in TreeSet It will use a comparator, adding elements for sorting and unique validation,

now the problem is that if you use a comparator for roll no, it will be sorted using roll no and unique rolls. you cannot have both together in a treeet.

I suggest you go.

  • TreeSet here you concentrate on duplicate deletion
  • after you get unique data for ArrayList and sort them in any order
+5
Dec 16 '10 at 12:37
source share

Order

Answer by @ralph to using TreeSet with the specified comparator is good, use this.

Design

You should wrap your concept of a “student database” inside a class that provides and documents the right behavior, rather than just using an unprocessed collection. If getting student lists in specific orders is a design requirement, expose methods (possibly returning an Iterable<Student> that say this. You can do different things behind the scenes depending on the usage pattern:

  • Maintaining one or more students Set and / t 23> sort / index by area of ​​interest.
  • On-demand array sorting on demand using Arrays.sort() and the specified Comparator .

Example....

 final class StudentTable { private static final Comparator<Student> studentRollNoComparator = ...; private final SortedSet<Student> sortedByRollNo = new TreeSet<Student>(studentRollNoComparator); public Iterable<Student> studentsOrderedByRollNo() { return sortedByRollNo; } //see below public void addStudent(final Student foo) { ... } } 

Uniqueness

You need to override equals() and hashCode() in your Student class to compare only the student name. Then you will get uniqueness (silently) in your TreeSet . Obviously, if you do this, you need to program the code to check if there is studentSet.contains(newStudent) before inserting newStudent so that you know if you have a duplicate or not.

 final class Student implements Comparable { ... @Override public boolean equals(Object o) { return o!=null && o (instanceof Student) && ((Student)o).name.equals(this.name); } @Override public int hashCode() { return name.hashCode(); // good enough for this purpose } } 

With this in place, your code for inserting a student might look like this:

 void addNewStudent(final Student toAdd) { if (studentSet.contains(toAdd)) { throw new IllegalStateException("Student with same name as "+toAdd+" already exists."); } studentSet.add(toAdd); } 

Then your tree set is populated by students whose names are unique, and your add operation reports an error if not. (Throwing an exception is just one potential route, and only suitable if adding a student with a duplicate name in ACTUALLY is an exceptional condition, but you did not say.)

+4
Dec 16 2018-10-16
source share

You can initialize a new TreeSet using another comparator. - So, all you have to do is write a new Comparator (implements the java.util.Comparator interface), use this comparator to initialize a new TreeSet, and then add all the students to the set.

 TreeSet<Student> sortedByRollNo new TreeSet<Student>(new RollNoComparator()); sortedByRollNo.addAll(allStudents); TreeSet<Student> sortedByY new TreeSet<Student>(new YComparator()); sortedByY.addAll(allStudents); 

Each set of trees can have its own comparator for sorting, if no comparator is specified, then the set of trees uses the natural order of the given elements.

added

If you only need the name uniqe Students, you have two ways:

  • Implement a comparator so that it returns 0 if the students name is equal (but I believe it is so kind to crack).
  • First filter the students by name, and then sort them using rollNo,

A bit like this:

 TreeSet<Student> sortedByRollNo new TreeSet<Student>(new RollNoComparator()); sortedByRollNo.addAll(new TreeSet<Student>(allStudends)); //this uses the native comparator to filter by uniqe name 
+1
Dec 15 '10 at 7:03
source share

It is a pity that you are here late, here is an elegant solution:

  public class OwnSortedList<T> extends TreeSet<T> { private static final long serialVersionUID = 7109828721678745520L; public OwnSortedList(Comparator<T> levelScoreComparator) { super(levelScoreComparator); } public boolean add(T e) { boolean existsElement = false; Iterator<T> it = iterator(); while(it.hasNext() && !existsElement){ T nextElement = it.next(); if(nextElement.equals(e)){ // Element found existsElement = true; Comparator<? super T> comparator = comparator(); int compare = comparator.compare(nextElement, e); if(compare > 0){ remove(nextElement); super.add(e); //element added so return true return true; } } } if(!existsElement){ super.add(e); } return false; } } 
0
Aug 2 '13 at 8:38
source share



All Articles