Reputation: 926
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
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
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