In TreeSet, Sorting & Uniqueness of custom objects based on different properties

烈酒焚心 提交于 2019-11-30 09:03:24

in TreeSet It will use comparator while adding elements for sorting and unique check,

now the problem is if you use comparator for roll no you will have it sorted by roll no and unique roll nos too. you can't have both together in treeset.

I would suggest you to go for.

  1. TreeSet here you concentrate about duplicate removal
  2. then once you have unique data go for ArrayList and sort it in any order you want
andersoj

Ordering

The answer by @ralph on using a TreeSet with a specified comparator is a good one, use that.

Design

You should wrap your concept of a "student database" inside a class that exposes and documents the correct behaviors, rather than just using a raw collection. If obtaining lists of students in particular orders is a design requirement, expose methods (perhaps returning Iterable<Student> that say that. Behind the scenes, you can do a variety of things depending on the usage pattern:

  • Maintain one or more Sets and or Maps sorting/indexing students by fields of interest.
  • On-demand in-place array sort using Arrays.sort() and a 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() on your Student class, to compare only the student name. Then you'll get uniqueness (silently) in your TreeSet. Obviously, if you do this, you need to code defensively to check to see if studentSet.contains(newStudent) before inserting newStudent, so you'll KNOW whether you've got 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, then your code to insert student can look like:

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

   studentSet.add(toAdd);
}

Your treeset is then full of students whose names are unique, and your add operation reports a failure if not. (Throwing an exception is just one potential route, and only appropriate if adding a student with a duplicate name is ACTUALLY an exceptional condition, but you didn't say.)

You can initialize a new TreeSet with an different comparator. - So all you have to do, is to write an new Comparator (implements java.util.Comparator interface), use this comparator to initialize the a new TreeSet and then add all 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 Tree Set can have its own comparator for sorting, if no comparator is specifed, then the Tree Set uses the natural ordering of the set elements.

added

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

  • Implement the comparator in a way, that it returns 0 if the name of the studens is equals (but i belive this is so kinde of hack).
  • First filter the students by name, and then sort them by 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

Sorry for being to late here, 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;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!