aspose file tools*
The moose likes Beginning Java and the fly likes Help needing in using Comparator to sort BY multiple elements in ArrayList Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Help needing in using Comparator to sort BY multiple elements in ArrayList" Watch "Help needing in using Comparator to sort BY multiple elements in ArrayList" New topic
Author

Help needing in using Comparator to sort BY multiple elements in ArrayList

Melinda Savoy
Ranch Hand

Joined: Jun 21, 2005
Posts: 386

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: 386

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: 36508
    
  16
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: 386

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
Sheriff

Joined: Aug 03, 2008
Posts: 9280
    
  17

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: 386

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
Sheriff

Joined: Aug 03, 2008
Posts: 9280
    
  17

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: 1666
    
    7

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: 386

Ankit,

Here is the CommonListItem class and I will try to just use compare method, thanks :

Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9280
    
  17

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
Sheriff

Joined: Aug 03, 2008
Posts: 9280
    
  17

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: 386

Thanks for all the help. I will try my initial code again.

Regards.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36508
    
  16
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: 36508
    
  16
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.
 
Don't get me started about those stupid light bulbs.
 
subject: Help needing in using Comparator to sort BY multiple elements in ArrayList
 
Similar Threads
Help needed on use of the Comparable interface
Please Help - Remove only the duplicated ITEM and NOT the original item that was duplicated.
alphabetizing lists
Sorting Table Columns
Sorting List By Comparator