Java Tips Weblog

  • Blog Stats

    • 2,572,379 hits
  • Categories

  • Archives

Column Comparator

Posted by Rob Camick on October 16, 2008

Java provides basic support for sorting data in Lists and Arrays by using the Collections.sort(…) and Arrays.sort(…) methods respectively. This works great when you have a single column of data in the List, an Array of Strings or a List of Integers, for example. But what happens when the data to be sorted is a List or an Array itself? In this case you would want to sort on a specific column and the data type to be sorted may be unknown. Java does not support this so what can you do?

Well, the answer is that you need to write a custom Comparator to handle these situations. For example, to sort a List where each item is an Array of Strings you could sort on the first column of the String Array with the following custom Comparator:

public class Column0Comparator implements Comparator<String[]>
{
    public int compare(String[] array, String[] anotherArray)
    {
        return array[0].compareTo( anotherArray[0] );
    }
};

A simple test that uses this custom Comparator might be like:

List stringArrays = new ArrayList();
stringArrays.add(new String[] {"x", "y", "z"});
stringArrays.add(new String[] {"a", "b", "c"});
Collections.sort(stringArrays, new ColumnOComparator()); 

Now what happens when you want to sort on the second column? I guess you could just copy the class and change all the “0” to “1”.

However, a better approach would be to make this Comparator flexible so that you could sort on any column and on any type of data found in that column. This was the guiding principal behind the design of the ColumnComparator class. Using this class you will be able to:

  1. Use the Arrays.sort() method with the ColumnComparator to sort Arrays. All rows in the Array must be of the same class, but they can be either:
    • an Array
    • a List
  2. Use the Collections.sort(…) method with the ColumnComparator to sort Lists. All rows in the List must be of the same class, but they can be either
    • a List
    • an Array

Using the ColumnComparator you will also be able to set a few properties to control the sort

  • ascending (the default) or descending
  • ignore case (the default) or use case. This property is only used when sorting Strings
  • nulls last (the default) or nulls first

The ColumnComparator can be used to sort an Arry containing primitives. In this case only the ascending/descending property will be relevant.

For example, lets start with a simple JTable with a few rows of data:

The data in the table comes from the DefaultTableModel. This model stores the data in a Vector of Vectors, so if we wanted to sort the data in ascending order based on the Integer column we would do something like this to get the attached result:

DefaultTableModel model = (DefaultTableModel)table.getModel();
Vector vector = model.getDataVector();
ColumnComparator cc = new ColumnComparator(1);
Collections.sort(vector, cc);
table.repaint();

Note, the ColumnComparator can be reused to provide sorting on multiple columns. Something like:

ColumnComparator cc = new ColumnComparator(1);
Collections.sort(vector, cc);
cc.setColumn(2);
Collections.sort(vector, cc);

Of course this will require two passes to sort the data which is not the most efficient, but will not be a problem on small amounts of data.

Get The Code

ColumnComparator.java

Related Reading

Java API: java.util.Arrays.sort( … )
Java API: java.util.Collections.sort( … )
Java API: java.util.Comparator

7 Responses to “Column Comparator”

  1. Lyudmila said

    There is a problem opening the the ColumnComparator.java

    Could you please help?

    Thanks,
    Lyudmila

  2. SJ said

    Thanks ! This helped me finally solve a problem that I had been overthinking :)

  3. Gone said

    new ColumnComparator(1);
    where does l come from??my compiler gives an error message that this constructor doesn’t exist..i can use only an empty constructor

  4. Anonymous said

    thanks Rob, this is very helpful. now I want to sort in descending order… what should I do???

Leave a comment