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:
- 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
- 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
Related Reading
Java API: java.util.Arrays.sort( … )
Java API: java.util.Collections.sort( … )
Java API: java.util.Comparator
Lyudmila said
There is a problem opening the the ColumnComparator.java
Could you please help?
Thanks,
Lyudmila
Rob Camick said
Thanks for the feedback. It appear the website where I host my source code is down. I’ll look into it.
SJ said
Thanks ! This helped me finally solve a problem that I had been overthinking :)
Rob Camick said
Good to see this got you heading in the right direction….
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
Rob Camick said
Look at the source code. There are 3 constructors and they all take a column as a parameter. Maybe you have another class by the same name somewhere on your machine?
Anonymous said
thanks Rob, this is very helpful. now I want to sort in descending order… what should I do???