WilliamShatner
WilliamShatner

Reputation: 926

Is there an easy way to sort an arraylist in this manner?

I'm wondering if there is a way to sort an Arraylist of custom objects to fit the situation explained below? I'm assuming I'll have to write a custom comparator.

Let's say I have an object class that looks like this:

public class Person {
    private String status;    //options: Online, Away, Offline
    private String name;      //Person's name
    private Date date;        //Last signed on

    //basic constructor
    public Person() {
        //set default values
    }

    //constructor to set all variables
    public Person(String s, String n, Date d) {
        status = s;
        name = n;
        date = d;
    }

    //setters & getters for each of the fields
}

Sorting based on name and date should be fairly easy. However, I'm wondering how I would sort based on the status? I would like to be able to sort my array based on whether the person is currently online and also who is offline. I'm not too concerned with who is away.

The above class is just an example class. My actual class has a JLabel set an icon based on the status. The setText() remains unused. I thought of a possibility of setting the label to values of 0, 1, and 2 and just using a typical integer comparator but I wasn't sure if that was an advised way of doing it.

Surely I'm missing an obvious solution here, so perhaps a comment or link can provide the necessary information. I know there are tons of 'Sort Arraylist' threads here at SO and I've browsed a lot of them. Most of them are just sorting Strings alphabetically or Integers though.

Upvotes: 2

Views: 355

Answers (3)

Thorn
Thorn

Reputation: 4057

I suggest we handle the status as an enumerated data type instead of a String where it can only be one of a few strings. This makes it easy to write a readable compareTo method:

public class Person implements Comparable<Person> {
  private Status currentStatus;   
  private String name;      //Person's name
  private Date date;        //Last signed on

  enum Status {ONLINE, AWAY, OFFLINE};

  //basic constructor
  public Person()  {
     //set default values
  }

  //constructor to set all variables
  public Person(Status s, String n, Date d) {
     currentStatus = s;
     name = n;
     date = d;
  }

 /**
  *   Order the Persons first by status where all ONLINE Persons are listed first.
  */
  @Override
  public int compareTo(Person other) {
     if(other.currentStatus == currentStatus)
        return name.compareTo(other.name);

     return currentStatus.ordinal() - other.currentStatus.ordinal();
  }
}   

Upvotes: 1

Tareq
Tareq

Reputation: 689

Using enums can be useful here enum MyEnum { ONLINE, AWAY, OFFLINE;}

Upvotes: 1

radai
radai

Reputation: 24212

if i understand correctly you basically want to sort on 2 fields - the major field is status (so people of the same status are bunched together) and then, whithin each gruop of people with the same status, by name.

a comparator that does this looks like this:

 public class CompositePersonComparator implements Comparator<Person> {    
    @Override
    public int compare(Person a, Person b) {
       //1st and foremost - see if they are not of the same status.
       int statusComparison = a.getStatus().compareTo(b.getStatus());
       if (statusComparison!=0) return statusComparison;
       //logical else - same status, sort by name
       return a.getName().compareTo(b.getName());
    }
 }

Upvotes: 4

Related Questions