Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare by multiple methods in java compareTo? [duplicate]

Tags:

java

compareto

I don't think that's the best way to word that title but I can't think of a better way to word it. Here's my problem: I have to write a method that compares in several different ways. If the last names are the same, I then need to compare by first name. If the first names are the same, then I need to sort by section. What would be the most effective way to sort a data structure in this hierarchy? Here's what I've currently got and I think I understand why it doesn't work but I can't come up with a different way to write this function:

//Student class structure, each field has a public get/set method
public class Student implements Comparable<Student>
{
  private String fname;
  private String lname;
  private int section;
}

//My current compareTo method
@Override
public int compareTo(Student s)
{
  /*
    -compare by last name
    -if the same, compare by first name
    -if the same, compare by section
  */

  String slast = s.getLastName();

  if(lname.compareTo(slast) == 0)
  {
    String sfirst = s.getFirstName();

    if(fname.compareTo(sfirst) == 0)
    {
      int sclass = s.getSection();

      return Integer.compare(section, sclass);
    }

    else
    {
      return fname.compareTo(sfirst);
    }
  }

  else
  {
    return lname.compareTo(slast);
  }
}
like image 798
John Porterfield Avatar asked Sep 08 '25 11:09

John Porterfield


2 Answers

You can create a Comparator for your Student class this way:

Comparator<Student> comparator = Comparator
        .comparing(Student::getLastName)
        .thenComparing(Student::getFirstName)
        .thenComparing(Student::getSection);

And then use this comparator (instead of implementing Comparable interface) to sort a list with Student objects, or to create a TreeMap with these objects:

Collections.sort(listOfStudents, comparator);
TreeMap<Student> mapOfStudents = new TreeMap<>(comparator);
like image 141
ardenit Avatar answered Sep 11 '25 07:09

ardenit


You don't have to use getters or setters if you're overriding compareTo. You can also forgo the else/return statements since they're terminal return statements, and just use return.

@Override
public int compareTo(Student s) {
    if (lname.compareTo(s.lname) == 0) {
        if (fname.compareTo(s.fname) == 0) {
            return section.compareTo(s.section);
        }
        return fname.compareTo(s.fname);
    }
    return lname.compareTo(s.lname);
}
like image 21
Compass Avatar answered Sep 11 '25 07:09

Compass