2010-09-27 66 views
0

我在用集合排序時遇到了棘手的問題。用java中的集合排序

我有一個包含類似下面

HashMap<String,QuoteBean> mapToSort=new HashMap<<String,QuoteBean>(); 

一些事情QuoteBean基本上是一個Java bean具有與setter和getter方法 它看起來像以下屬性是一個HashMap。

//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 

現在,當我從圖中的值,我通常把它像這樣

Collection values=mapToSort.values();//which will return all the values in the map 

這個值基本上是QuoteBean對象的集合。 我想在將它發送給客戶端之前對它們進行排序。 現在我可以使用比較器接口並對其進行排序.. 但問題是頻繁排序標準的變化。 我的意思是有時候客戶想要用符號來排序,有時客戶想要用總收益改變一些時間。 標準經常更改。 是否有寫的「比較」函數重載的方法,並且將滿足所有條件...

是否有解決這個問題的任何好辦法..

我真的很感激,如果有一個人可以回覆此話題

謝謝,

+0

大家,喜歡的JavaOne? :) – Bozho 2010-09-27 19:10:49

回答

6

是的。實現java.util.Comparator接口,並使用重載的方法:Collections.sort(list, comparator)(你需要創建從集合的元素的新List,例如new ArrayList(collection)

所以,你可以有:

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 } 
} 

,然後用Collections.sort(list, ChangeQuoteComparator.INSTANCE);

請注意,這是一個很好的做法,聲明每個比較的單一實例,而不是每次都實例吧:

public static final ChangeQuoteComparator INSTANCE = 
    new ChangeQuoteComparator(); 

要擴展的東西多一點,可以用不同的比較類型定義一個enum

public enum ComparisonType { 
    CHANGE, CURRENT_PRICE; // etc.. 
} 

並定義一個Map到每個比較型與適當的比較器相匹配:

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); 
} 

然後讓客戶指定他想要的比較

public List<QuoteBean> getOrdered(ComparisonType type, // other criteria) { 
    List<QuoteBean> list = new ArrayList<QuoteBean>(getQuotesCollection()); 
    Collections.sort(list, comparators.get(type)); 
    return list; 
} 
2

您可以使用Comparator並創建多個實現,或者您可以使用動態實現來更改工作方式,方法是在其上設置參數。


對於多個實現你可以看看@Bozho的答案。

對於動態執行,你可以做這樣的事情:

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); 
     } 
    } 
} 

甚至更​​好:

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; 
    } 
} 

這種方式,你可以使用任何你想要的比較,甚至將被執行多比較按照正確的順序。

+0

@Colin Hebert當你說multipleimplementation ..Could介意給一個例子或pusdo代碼你是什麼意思.. – swati 2010-09-27 19:00:50

+0

@科林赫伯特可以介意解釋動態實施與一個例子... – swati 2010-09-27 19:01:54

+0

@ user436175,現在在那裏就是一個例子。但是在重讀了原來的問題之後,我可能會誤解這個問題。我以爲你也想同時在不同的元素上進行比較。但它仍然回答了這個問題:) – 2010-09-27 19:33:14

1

您必須爲每種情況編寫一個比較器,並根據客戶要求選擇比較器。

1

最好的解決方案是使用apache公共的beancomparator對象。你可以這樣做

BeanComparator comparator = new BeanComparator("currentPricel"); Collections.sort(yourlisthere, comparator);

,或者你可以直接做

Collections.sort(yourlisthere, new BeanComparator("currentPricel"));