aspose file tools*
The moose likes Beginning Java and the fly likes Sorting by 3 variables dynamically in arrayList Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Sorting by 3 variables dynamically in arrayList" Watch "Sorting by 3 variables dynamically in arrayList" New topic
Author

Sorting by 3 variables dynamically in arrayList

Luke Zechariah
Ranch Hand

Joined: Sep 27, 2005
Posts: 117


I have 2 jsp screens, on the first screen I input the search-sort criteria and on the second screen I am displaying a list of sorted variables from an object. I am using struts.

Following is info of what is displayed on the 2nd screen.
First Name
Last Name
Account number
Transfer date
City
Account type
transaction number
office Code

On the first jsp screen (where we have the search criteria) there are 3 selects (ie drop downs) the user will select 3 out the 8 variables above. For example: the user may select sort by First Name, City, and office Code. Another user may select sort by City, transfer date, Account type. So the user has a choice to choose any 3 out of the 8 variables above. After clicking search, I am populating the objects that have the above variables in an arraylist and then I am trying to programmatically sort this arraylist of objects before displaying them on the second screen. Please help how could I modify the comparator example code below.




I have assumed the above code with a search criteria by FirstName then City then OfficeCode. But in real time the user can choose any of the three from the 8 variables dynamically, then how would I code for that.

Thanks for your time in advance.
Lz.
Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575

can you do this? sort in ascending *and* descending order! .
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Here are a few possible approaches:

1) Define explicit Comparators for every permutation of fields they might sort by (and 3 out of 8 is 8 * 7 * 6 = 336)

2) Define a single Comparator that takes field names to sort by and uses reflection to get the values of those fields from the objects it's comparing.

3) Define a single Comparator that takes fieldNames but where you write an explicit mapping from those field names to individual per-field Comparators.
Luke Zechariah
Ranch Hand

Joined: Sep 27, 2005
Posts: 117

Thank you for the replies.

Seetharaman, do you mean can my code do the asc or desc sorting?

Jeff, I would like to go with either option 2 or 3. But can you explain them more, in a code or something for more clarity. I am not good at these reflections or mappings thing.

Thanks a lot for your time again.
Lz.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Luke Zechariah wrote:

Jeff, I would like to go with either option 2 or 3. But can you explain them more, in a code or something for more clarity. I am not good at these reflections or mappings thing.

Thanks a lot for your time again.
Lz.


Okay, first, do you know how to write a simple Comparator to compare on a single, predetermined field? For instance, "Write a Comparator that can be used to sort a list of Person objects by lastName." Have you ever done that? If not, you MUST do that before you go any further. If you don't, you're wasting your time and the time of anybody trying to help you here.

Next, do you understand how to write a Comparator to order based on multiple predetermined fields? For instance, "Write a Comparator that can be used to sort a list of Person objects by lastName and then if lastName is equal by firstName." Have you ever done that? If not, then, again, you MUST do this first.

...

Okay, so, now that you understand that stuff...

If you're going to go with a single Comparator, then you have to be able to tell that Comparator which fields to compare, right? And you need a way to get from those field names to the actual values in the fields being compared, right?



So, which approach do you want to take? #2 reflection or #3 custom mapping? Pick one, study up on it, take your best shot, and post again if you get stuck. (After first making sure you can work with Comparators where the fields aren't being chosen on the fly, of course.)
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18155
    
    8

Another option: put your data into a database table, then generate a query of the form

Then you let SQL and your database deal with the ugly programming details that you'd rather not get involved in.
Luke Zechariah
Ranch Hand

Joined: Sep 27, 2005
Posts: 117
Here is the below code for sorting using reflections. I have the following example from this link:

DynamicSort
Code


Here I am using only 2 variables to sort. That is Sortby variable1, Sortby variable2. The question I have is if I increase the number of variables to sort then the combinations also increase in the "compare" method for DynamicComparator.java. Is there way you would suggest?



EmployeeTO.java



DynamicTest.java



DynamicComparator.java

Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3454
    
  47

I'd suggest creating a CompoundComparator class. This class would implement the Comparator interface, and take a list of Comparators in its constructor. The compare() method would then try all the comparators in the order in which they were given and returned the first nonzero value returned by one of the comparators. If all comparators return zero, the CompoundComparator returns zero as well. You should be able to code the class in a few minutes. It can easily be made generic.

Create a comparator or comparators to compare by one field at a time. Do it whatever you like - reflection, static code, anything. All you need is to be able to create comparator for a given field dynamically.

Take a list of requested fields and create a corresponding list of comparators. Create a CompoundComparator from that list.

Voila!

If you want to reverse the order of comparison for one field, use Collections.reverseOrder(). You can then invert the order of any comparator in the CompoundComparator class independently of the others.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7081
    
  16

Luke Zechariah wrote:Here is the below code for sorting using reflections.

Personally, I would only use reflection if I was planning to write some sort of "universal" Comparator (ie, one which doesn't even know the class it's trying to compare); but I have to admit to an extreme aversion to reflection code.

Secondly, I think that converting to Strings is not a good idea (it rarely is) - you're likely to get bogged down in the detail of how each field gets converted.
An alternative would be to impose the simple rule that every field to be compared must be Comparable. This is already the case for Strings; and will also be the case for any boxed number. If your AccountInfo class contains any other fields that aren't, you have two choices:
1. Make them Comparable.
2. Don't allow them to be chosen.

I think I'd probably create an enum which includes all the sortable fields in your Account object, viz:and then use that to create a dynamic Comparator, viz:The nice thing about that is that you can then just associate any given column with an AccountField value.

Of course, it's only one possibility; and there are lots of others ([Edit] and now I've looked at Martin's suggestion properly, it's probably even better).
I should also point out that I haven't tried (or compiled) the above; but I'm pretty sure the idea is sound.

Good luck.

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Artlicles by Winston can be found here
Luke Zechariah
Ranch Hand

Joined: Sep 27, 2005
Posts: 117

Thank you Martin and Winston for the input. Winston thanks for the code, I will test my code per your suggestion and see how it works. I took up Martin's suggestion and it is working. Here is code of what I did, I used ComparatorChain and sorted it.

DynamicTest.java




EmployeeTO.java



You can add any number of variables to your POJO, and sort them accordingly.

Thank you everyone for your time and consideration.
Luke.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7081
    
  16

Luke Zechariah wrote:Thank you everyone for your time and consideration.

You're welcome.

Oddly enough, your thread got me thinking about it too; and I've now added a nice little Index class of my own that combines Martin's and my suggestions.

Winston
 
jQuery in Action, 2nd edition
 
subject: Sorting by 3 variables dynamically in arrayList
 
Similar Threads
Comparator and Comparable
Comparator and Comparable
Sorting ArrayList of MemberBean objects
Comparable/Comparator query
Need Help in Sorting Multiple columns!