| Author |
Help needing in using Comparator to sort BY multiple elements in ArrayList
|
Melinda Savoy
Ranch Hand
Joined: Jun 21, 2005
Posts: 375
|
|
I have a a list called commonList.getCommonListItems.
In this list I have multiple elements and I'm needing to sort by 2 elements within this list: first by binSortCode and then by itemDescr
I've been googling and trying to get some help but am having problems trying to understanding comparable vs comparator. I had used comparable to sort on a single element and it worked find but when trying to sort on multiple elements I'm not able to make it work.
I have created a comparator class where I am trying to sort first on binSortCode and then sort on itemDesc, please see the following:
The outcome that I'm getting is that the binSortCode is in desc order and the itemdesc is in asc order.
As stated above, I need the sort to reflect: binSortCode in ASC order and then the itemDesc in ASC order.
Any help or direction would be greatly appreciated.
Regards.
|
 |
Robert Waals
Greenhorn
Joined: Dec 22, 2006
Posts: 14
|
|
An object implementing the Comparable interface defines how to compare itself against other objects. When implementing this interface you have to implement the compareTo method. For more information click here.
A Comparator class allows you to sort on the criteria you specify yourself (or by using the compareTo method when you want to use both approaches). To sort on multiple levels you can create a nested Comparator class.
A small example:
This can then be used in the following way:
Regards,
Robert Jan
|
 |
Melinda Savoy
Ranch Hand
Joined: Jun 21, 2005
Posts: 375
|
|
Robert,
I guess I'm not clear by what you sent. Are you saying that I need to add this CompositeComparator class to work with what I already have?
|
 |
Campbell Ritchie
Sheriff
Joined: Oct 13, 2005
Posts: 32675
|
|
|
There is a simpler alternative, which is to sort with two different Comparators one after the other. More details in the API where the important fact is that the sort is "stable."
|
 |
Melinda Savoy
Ranch Hand
Joined: Jun 21, 2005
Posts: 375
|
|
Campbell,
I tried doing what you've suggested but it did not keep the sort from the first comparator and just overwrote what sort was there with the second comparator.
I'll look at he API again. Perhaps I did something wrong.
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9189
|
|
Campbell Ritchie wrote:There is a simpler alternative, which is to sort with two different Comparators one after the other.
Well Campbell I don't know if I am right, but I think this will not work. If I understand it correctly, the sorting is to be done in this manner
Suppose I have a student class with fields name and age. Now I have to sort it with Age and if age is same for two or more children, then I have to sort them according to their name. Example if I have this list
Ankit, 20
Mayur, 23
Ram, 20
Aakash, 23
Then the sorting should be
Ankit, 20
Ram, 20
Aakash, 23
Mayur, 23
This can be done by using the comparator that you have already implemented. I made this code to show the functionality
|
SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
|
 |
Melinda Savoy
Ranch Hand
Joined: Jun 21, 2005
Posts: 375
|
|
Ankit,
I think your example looks exactly, or almost, like the code that I'm having issues with that I posted initially.
However, the sort is not being done first by the binSortCode and THEN by the itemdesc fields. That is where my dilemma is.
The sort results I got where:
the binSortCode was in DESC order and the itemDesc was in ASC order.
I need the binSortCode to sort first then followed by the itemDesc to sort second maintaining the first sort of the binSortCode.
Hope that makes sense. Can you please look at the initial post? Thanks.
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9189
|
|
|
Can you do two things. Just post the code of the CommonListItem class and also try compareTo instead of compareToIgnoreCase...
|
 |
Jelle Klap
Bartender
Joined: Mar 10, 2008
Posts: 1409
|
|
Ankit Garg wrote:
Campbell Ritchie wrote:There is a simpler alternative, which is to sort with two different Comparators one after the other.
Well Campbell I don't if I am right, but I think this will not work. If I understand it correctly, the sorting is to be done in this manner
It should work if the sorting alorithm is stable (meaning equal objects aren't reorderd), like Campbell said.
For instance, let's say you have an unsorted list of objects, each of which contains two fields. This could be represented by the following sequence:
D, 3
A, 2
D, 6
A, 8
B, 5
A, 3
C, 1
Now, let's say you want this list to be first sorted alphabetically (ignoring character case for the sake of simplicitly) by the first column and then nummerically by the by the second column.
Let's say you've written two distinct Comparator implementations that do just that. First you should use the Comparator that sorts the list nummerically - which is the least significant field in the overall sorting sequence.
You'll end up with the following sequence:
C, 1
A, 2
D, 3
A, 3
B, 5
D, 6
A, 8
Obviously you're not there yet, because you still have to meet the primary sorting requirement, so let's apply that Comparator to the intermediate result:
A, 2
A, 3
A, 8
B, 5
C, 1
D, 3
D, 6
Et voilá! If you apply the Comparators sequentially in a back-to-front order (i.e. first sorting by the field that the final sequence should be ordered by last) it all works out beautifully.
|
Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
|
 |
Melinda Savoy
Ranch Hand
Joined: Jun 21, 2005
Posts: 375
|
|
Ankit,
Here is the CommonListItem class and I will try to just use compare method, thanks :
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9189
|
|
Jelle you are right. I have never every thought or heard about that solution. I was hesitating to write that Campbell was wrong as I know that he is among the most respected people out here. That's why I wrote
I don't know if I am right, but I think this will not work
I knew that I would be wrong at the end
I still have a lot to learn before I can dare to directly say that Campbell you are wrong
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9189
|
|
|
Melinda I don't see anything wrong with that code. Why don't you try what Campbell and Jelle said i.e. implement two comparators...
|
 |
Melinda Savoy
Ranch Hand
Joined: Jun 21, 2005
Posts: 375
|
|
Thanks for all the help. I will try my initial code again.
Regards.
|
 |
Campbell Ritchie
Sheriff
Joined: Oct 13, 2005
Posts: 32675
|
|
Why don't you tell me when you think I am wrong? Joanne Neal does all the time!
Actually, you are right. You have to implement one Comparator, then if that returns 0 try the other Comparator. Since the sorting is "stable", if both Comparators return 0, then the two elements are left in their initial locations.
Anyway some good came of it; my mistake made for a much more interesting discussion.
|
 |
Campbell Ritchie
Sheriff
Joined: Oct 13, 2005
Posts: 32675
|
|
|
By the way, that equals() method looks suspect to me. The equals() method takes Object as a parameter, so you can pass any reference type to it, but anything other than the correct type will generate a ClassCastException. You need to test for type (details in books like Effectvie Java by Joshua Bloch, or on that most useful website of Angelika Langer's), and you also need to override the Object#hashCode() method.
|
 |
 |
|
|
subject: Help needing in using Comparator to sort BY multiple elements in ArrayList
|
|
|