Reputation: 2139
I have a tricky question in sorting with collection.
I have a HashMap which contains some thing like the following
HashMap<String,QuoteBean> mapToSort=new HashMap<<String,QuoteBean>();
QuoteBean is basically a java bean which has properties with setter and getter methods Which looks like the following.
//class QuoteBean defination
Class QuoteBean implements Serializable{
private BigDecimal currentPricel
private BigDecimal change;
private BigDecimal TotalChange;
private String symbol;
//with getter and setter methods
}//end of the class
Now when i get the values from the map i usually get it like this
Collection values=mapToSort.values();//which will return all the values in the map
This values is basically a collection of QuoteBean objects. I want to sort the beans before sending it to the client. Now i can use the comparator interface and sort it .. But the problem is the sorting criteria changes frequently . I mean some time the client wants to sort with symbol,some times the client wants with change some times with total gain. The criteria changes very often. Is there a way to write the " compare " function to overload and which will satisfy all the conditions...
Is there any good way of solving this problem..
I would really appreciate if some one can reply to this topic
Thanks,
Upvotes: 0
Views: 1873
Reputation: 1296
The best solution to this would be to use a beancomparator object from apache commons. You can do something like
BeanComparator comparator = new BeanComparator("currentPricel");
Collections.sort(yourlisthere, comparator);
or you can directly do a
Collections.sort(yourlisthere, new BeanComparator("currentPricel"));
Upvotes: 1
Reputation: 93197
You can use the Comparator
and create either multiple implementations, or you can use a dynamic implementation where you change the way it works by setting parameters on it.
For the multiple implementations you can take a look at @Bozho answer.
For the dynamic implementation you could do something like that :
public class DynamicComparator implements Comparator<QuoteBean> {
public boolean compareCurrentPricel = false;
public boolean change = false;
//Setters for the booleans
@Override
public int compare(QuoteBean b1, QuoteBean b2) {
int currentSort = 0;
if(compareCurrentPricel && currentSort == 0){
currentSort = compareCurrentPrice1(b1, b2);
}
if(change && currentSort == 0){
currentSort = compareChange(b1, b2);
}
}
}
Or even better :
public class MultipleComparators<T> implements Comparator<T> {
public List<Comparator<? super T>> comparators;
public MultipleComparators(List<Comparator<? super T>> comparators){
this.comparators = comparators;
}
@Override
public int compare(T b1, T b2) {
int returned = 0;
for(Comparator<? super T> c : comparators){
returned = c.compare(b1, b2);
if(returned != 0){
break;
}
}
return returned;
}
}
This way you can use any comparator you want and even multiple comparators which will be executed in the right order.
Upvotes: 2
Reputation: 597422
Yes. Implement the java.util.Comparator
interface and use the overloaded method: Collections.sort(list, comparator)
(you will need to create a new List
from the elements of the collection, for example new ArrayList(collection)
)
So you can have:
public CurrentPriceQuoteComparator implements Comparator<QuoteBean> {
@Override
public int compare(QuoteBean b1, QuoteBean b2) { // implement comparison }
}
public ChangeQuoteComparator implements Comparator<QuoteBean> {
@Override
public int compare(QuoteBean b1, QuoteBean b2) { // implement comparison }
}
And then use Collections.sort(list, ChangeQuoteComparator.INSTANCE);
Note that it is a good practice to declare a singleton instance of each comparator, instead of instantiating it each time:
public static final ChangeQuoteComparator INSTANCE =
new ChangeQuoteComparator();
To extend things a little more, you can define an enum
with the different comparison types:
public enum ComparisonType {
CHANGE, CURRENT_PRICE; // etc..
}
and define a Map
to match each comparison type with the appropriate comparator:
private static final Map<ComparisonType, Comparator<QuoteBean>> comparators =
new HashMapMap<ComparisonType, Comparator<QuoteBean>>();
static {
comparators.put(ComparisonType.CHANGE, ChangeQuoteComparator.INSTANCE);
comparators.put(ComparisonType.CURENT_PRICE,
CurrentPriceQuoteComparator.INSTANCE);
}
and then let the client specify which comparison he'd like
public List<QuoteBean> getOrdered(ComparisonType type, // other criteria) {
List<QuoteBean> list = new ArrayList<QuoteBean>(getQuotesCollection());
Collections.sort(list, comparators.get(type));
return list;
}
Upvotes: 6
Reputation: 13799
You will have to write a comparator each for every situation and depending on the client requirement you can choose the comparator.
Upvotes: 1