Сортировка по коллекциям в java - PullRequest
0 голосов
/ 27 сентября 2010

У меня каверзный вопрос в сортировке с коллекцией.

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

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

QuoteBean - это в основном Java-бин, который имеет свойства с методами set и getter. Который выглядит следующим образом.

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

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

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

Спасибо

Ответы [ 4 ]

6 голосов
/ 27 сентября 2010

Да. Реализуйте интерфейс 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 голосов
/ 27 сентября 2010

Вы можете использовать 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;
    }
}

Таким образом, вы можете использовать любой компаратор, который вы хотите, и даже несколько компараторов, которые будут выполняться в правильном порядке.

1 голос
/ 27 сентября 2010

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

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

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

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

1 голос
/ 27 сентября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...