Esha Ghosh
Esha Ghosh

Reputation: 157

How to sort a list of class objects on one of its fields?

I have a list of DataPoint objects. The class definition is:

public static class DataPoint
     {
         public Comparable X;
         public Comparable Y;
         public Comparable Z;

         public String text; 

               ...
          }

"list" is an ArrayList of DataPoint objects. How do I sort list only on the X value? Would Collections.sort(list, comparator) be used here?

Upvotes: 2

Views: 1108

Answers (2)

Jack
Jack

Reputation: 133577

You have two choices:

First solution is meaningful if you want to give a natural ordering on your objects (which will be the most used one). Usually it's the one you use first while you use comparators just when you need additional orderings.

They both behave in the same way but Comparable<T> is inherently attached to the object as it is its default comparison algorithm. Whenever sorting is involved the default one will be used unless you specify another one.

class DataPoint implements Comparable<DataPoint> {
  @Override
  public int compareTo(DataPoint o) {
    return X.compareTo(o.X);
  }
}

Mind that when you need to compare objects you usually need also other operations on them so take care of overriding hashCode() and equals(Object o). The latter is used in sorting as documentations states:

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. ... It is strongly recommended (though not required) that natural orderings be consistent with equals.

This means that if you just compare X variable then two different DataPoint objects with same X will be considered equal with respect to compareTo. This can lead to strange situations.

Upvotes: 3

Mikita Belahlazau
Mikita Belahlazau

Reputation: 15434

Yes, you should create specific comparator for each field. Example:

Comparator<DataPoint> compByX = new Comparator<DataPoint>() {
    @Override
    public int compare(DataPoint left, DataPoint right) {
        return left.X.compareTo(right.X);
    }
};
Collections.sort(list, compByX);

Upvotes: 5

Related Questions