繁体   English   中英

用Java中的集合排序

[英]Sorting with collections in java

在对集合进行排序时,我有一个棘手的问题。

我有一个包含以下内容的HashMap

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

QuoteBean基本上是一个Java bean,它具有setter和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对象的集合。 我想在将其发送给客户端之前对bean进行排序。 现在,我可以使用比较器接口并对它进行排序了。但是问题是排序标准经常更改。 我的意思是有些时候客户想要用符号来排序,有些时候客户想要随着总收益而变化。 标准经常更改。 有没有一种方法可以将“ compare”函数编写为重载,并且可以满足所有条件...

有什么好的方法可以解决这个问题。

如果有人可以回复这个话题,我将不胜感激

谢谢,

是。 实现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;
 }

您可以使用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;
    }
}

这样,您可以使用所需的任何比较器,甚至可以按正确的顺序执行多个比较器。

您将必须针对每种情况编写一个比较器,并且可以根据客户要求选择比较器。

最好的解决方案是使用来自Apache Commons的beancomparator对象。 你可以做类似的事情

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

或者你可以直接做一个

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM