2010-09-27 2 views
0

У меня есть сложный вопрос при сортировке с коллекцией.Сортировка с коллекциями в java

У меня есть HashMap, который содержит некоторые вещи, как следующего

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

QuoteBean является в основном Java Bean, который имеет свойство с установкой и получением методами Который выглядит следующим образом.

//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. Я хочу сортировать компоненты, прежде чем отправлять их клиенту. Теперь я могу использовать интерфейс компаратора и сортировать его. Но проблема в том, что критерии сортировки часто меняются. Я имею в виду некоторое время, когда клиент хочет сортировать с символом, несколько раз клиент хочет с изменением несколько раз с общим выигрышем. Критерии меняются очень часто. Есть ли способ, чтобы написать функцию «сравнить» перегружать и который удовлетворит все условия ...

Есть ли хороший способ решения этой проблемы ..

Я был бы очень признателен, если кто-то может ответить на эту тему

Thanks,

+0

Всеобщие, как JavaOne? :) – Bozho

ответ

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 Когда вы говорите несколько вариантов реализации. Не могли бы дать пример или код pusdo, что вы подразумеваете под этим. – swati

+0

@Colin Hebert не мог объяснить динамическую реализацию на примере ... – swati

+0

@ user436175, теперь там является примером. Но, перечитав оригинальный вопрос, я, возможно, неправильно понял вопрос. Я думал, что вы хотите сравнить и разные элементы одновременно. Но все же он отвечает на вопрос :) –

1

Вам нужно будет написать компаратор каждый для каждой ситуации и в зависимости от требований клиента вы можете выбрать компаратор.

1

Лучшим решением для этого было бы использовать объект beancomparator из сообщества apache. Вы можете сделать что-то вроде

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

или вы можете непосредственно сделать

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

Смежные вопросы