[英]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.