Gregg
asked on
Question about Comparators
Is it possible to use the same Comparator class to compare any attribute of type String?
Example:
I have a person object with attributes:
String: firstName, lastName, address1, city, state, zip
Integer: personID
Id like to be able to sort by any one attribute (firstname, lastname, and city for example).
Do i create a comparator class for each? FirstNameComparator, LastNameComparator, CityComparator, etc...
Or is it possible to create a comparator that accepts string? Is that what generics does?
Thanks!
Example:
I have a person object with attributes:
String: firstName, lastName, address1, city, state, zip
Integer: personID
Id like to be able to sort by any one attribute (firstname, lastname, and city for example).
Do i create a comparator class for each? FirstNameComparator, LastNameComparator, CityComparator, etc...
Or is it possible to create a comparator that accepts string? Is that what generics does?
Thanks!
You can have parameter set up in the constructor of yur comparator which will speify wjich attribute to us in comparison
Just include instance varaible say flag into your comparator abnd set it up n the constructor and then use this flag in compae() methiod to determine which field to use for comparison
Public class MyComp {
Int flag;
Public MyComp(int I){
This.flag = I;
}
Public int compare(Person p1, Person p2){
If(flag == 0){
// do comnparison on name
} Else if flag == 1 {
// do comparison on age
}
//etc
}
And theen you just say
Collections.sort(arraylis, new MyComp(0));
In anoteer case yiu crerate MyComp(1) etc.
Sorry for wrong case of the characcters in the coe above - this is mobile tricks
Ffrom my pohone
- hope you get the idxea
Int flag;
Public MyComp(int I){
This.flag = I;
}
Public int compare(Person p1, Person p2){
If(flag == 0){
// do comnparison on name
} Else if flag == 1 {
// do comparison on age
}
//etc
}
And theen you just say
Collections.sort(arraylis,
In anoteer case yiu crerate MyComp(1) etc.
Sorry for wrong case of the characcters in the coe above - this is mobile tricks
Ffrom my pohone
- hope you get the idxea
You sure can have compaator on Strings but in this acse it will be more convenient to have comparator on Person but with this flag parameter
You can use reflection to sort on any field you name. Here's a simple example:
https://suif.stanford.edu/svn/prpl/prpl_core/trunk/src/java/edu/stanford/prpl/common/GenComparator.java
https://suif.stanford.edu/svn/prpl/prpl_core/trunk/src/java/edu/stanford/prpl/common/GenComparator.java
SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
Thanks guys! Im looking into both options.
CEHJ: I find your example interesting. Is it a generally accepted approach? That would allow for me to use the Comparator for many custom classes and not have to recreate code like i did below - would you agree?
And since my last post, i put this together. I havent tested yet - it follows for_yans thought process. for_yan, what do you think?
CEHJ: I find your example interesting. Is it a generally accepted approach? That would allow for me to use the Comparator for many custom classes and not have to recreate code like i did below - would you agree?
And since my last post, i put this together. I havent tested yet - it follows for_yans thought process. for_yan, what do you think?
package util.sort;
import java.util.Comparator;
import logic.Contact;
/**
* This class represents a Comparator object for sorting
* two contacts. The attribute to sort by is passed in
* via constructor.
*/
public class SortBy implements Comparator<Contact> {
//Attribute that holds selection passed in constructor.
private SortByField whichToSort;
//Constructor
/**
* Constructor that accepts one parameter.
* @param whichToSort This is the value to sort by.
*/
public SortBy(SortByField whichToSort)
{
this.whichToSort = whichToSort;
}
/**
* Compare two contacts based on the Sort Field Enum Selection
* passed into Constructor.
*/
@Override
public int compare(Contact contact1, Contact contact2) {
int result = 0;
if(this.whichToSort.equals(SortByField.FIRST_NAME))
{
result = contact1.getFirstName().compareTo(contact2.getFirstName());
}
else if(this.whichToSort.equals(SortByField.LAST_NAME))
{
result = contact1.getLastName().compareTo(contact2.getLastName());
}
else if(this.whichToSort.equals(SortByField.CITY))
{
result = contact1.getCity().compareTo(contact2.getCity());
}
else if(this.whichToSort.equals(SortByField.STATE))
{
result = contact1.getState().compareTo(contact2.getState());
}
else if(this.whichToSort.equals(SortByField.ZIP))
{
result = contact1.getZip().compareTo(contact2.getZip());
}
return result;
}
/**
* This inner class represents the options for sorting.
*/
public enum SortByField {
//Enumeration Options
FIRST_NAME(0),
LAST_NAME(1),
CITY(2),
STATE(3),
ZIP(4);
private int sortByValue;
//Constructor
private SortByField(int sortByValue)
{
this.sortByValue = sortByValue;
}
/**
* Returns the sortByField as integer.
* Options include: FIRST_NAME, LAST_NAME, CITY, STATE, ZIP
* @return sortByValue - the value representing the ENUM selection.
*/
public int getSortByField()
{
return sortByValue;
}
}
}
yes, I think it should work, the way you wrote it
In gneral the decision will depend on your situation - if you really want to
sort all the time different classes by different fields, on the other hand sorting is defintely
not a bottleneck in your appliaction (that would be the case if you have moderatlye sized lists, which say you
first get from database - sure interaction with databse will be more of the bottleneck) then generality which you can
achivee with reflection would be of value
I still think in most of the cases folks are using more conventional way rather than doing reflection,
but if you have vwery many classes and in need of writing new comparator every other day - then reflection will be a good choice
sort all the time different classes by different fields, on the other hand sorting is defintely
not a bottleneck in your appliaction (that would be the case if you have moderatlye sized lists, which say you
first get from database - sure interaction with databse will be more of the bottleneck) then generality which you can
achivee with reflection would be of value
I still think in most of the cases folks are using more conventional way rather than doing reflection,
but if you have vwery many classes and in need of writing new comparator every other day - then reflection will be a good choice
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
>>CEHJ: I find your example interesting. Is it a generally accepted approach?
Well there exist for example google classes that use reflection. The overhead of reflection is generally exaggerated, but you should always benchmark these things rather than relying on anecdote
Well there exist for example google classes that use reflection. The overhead of reflection is generally exaggerated, but you should always benchmark these things rather than relying on anecdote
ASKER
I do like the reflection example and i will explore that in more detail. I am happy to have the conventional approach working. Thank you both for taking the time to help me learn this.
:)