2010-09-13 144 views
7

我有一个包含Quote对象的数组列表。我希望能够按名称,变化和百分比变化按字母顺序排序。我如何排列我的数据列表?如何使用多个排序条件对ArrayList进行排序?

package org.stocktwits.model; 

import java.io.Serializable; 
import java.text.DecimalFormat; 

    public class Quote implements Serializable { 

     private static final long serialVersionUID = 1L; 

     public String symbol; 
     public String name; 
     public String change; 
     public String percentChange; 
     public String open; 
     public String daysHigh; 
     public String daysLow; 
     public String dividendYield; 
     public String volume; 
     public String averageDailyVolume; 
     public String peRatio; 
     public String marketCapitalization; 
     public String yearHigh; 
     public String yearLow; 
     public String lastTradePriceOnly; 
     public DecimalFormat df = new DecimalFormat("#,###,###,###,###,##0.00"); 
     public DecimalFormat vf = new DecimalFormat("#,###,###,###,###,##0"); 

     public String getSymbol() { 
      return symbol; 
     } 
     public void setSymbol(String symbol) { 
      this.symbol = symbol; 
     } 
     public String getName() { 
      return name; 
     } 
     public void setName(String name) { 
      this.name = name; 
     } 
     public String getChange() { 
      return change; 
     } 
     public void setChange(String change) { 
      if(change.equals("null")){ 
       this.change = "N/A"; 
      } 
      else{ 
       float floatedChange = Float.valueOf(change); 
       this.change = (df.format(floatedChange)); 
      } 
     } 
     public String getPercentChange() { 
      return percentChange; 
     } 
     public void setPercentChange(String percentChange) { 
      if(percentChange.equals("null")) 
       percentChange = "N/A"; 
      else 
       this.percentChange = percentChange; 
     } 
     public String getOpen() { 
      return open; 
     } 
     public void setOpen(String open) { 
      if(open.equals("null")) 
       this.open = "N/A"; 
      else 
       this.open = open; 
     } 
     public String getDaysHigh() { 
      return daysHigh; 
     } 
     public void setDaysHigh(String daysHigh) { 
      if(daysHigh.equals("null")) 
       this.daysHigh = "N/A"; 
      else{ 
       float floatedDaysHigh = Float.valueOf(daysHigh); 
       this.daysHigh = (df.format(floatedDaysHigh)); 
      } 
     } 
     public String getDaysLow() { 
      return daysLow; 
     } 
     public void setDaysLow(String daysLow) { 
      if(daysLow.equals("null")) 
       this.daysLow = "N/A"; 
      else{ 
       float floatedDaysLow = Float.valueOf(daysLow); 
       this.daysLow = (df.format(floatedDaysLow)); 
      } 
     } 
     public String getVolume() { 
      return volume; 
     } 
     public void setVolume(String volume) { 
      if(volume.equals("null")){ 
       this.volume = "N/A"; 
      } 
      else{ 
       float floatedVolume = Float.valueOf(volume); 
       this.volume = (vf.format(floatedVolume)); 
      } 
     } 
     public String getDividendYield() { 
      return dividendYield; 
     } 
     public void setDividendYield(String dividendYield) { 
      if(dividendYield.equals("null")) 
       this.dividendYield = "N/A"; 
      else 
       this.dividendYield = dividendYield; 
     } 
     public String getAverageDailyVolume() { 
      return averageDailyVolume; 
     } 
     public void setAverageDailyVolume(String averageDailyVolume) { 
      if(averageDailyVolume.equals("null")){ 
       this.averageDailyVolume = "N/A"; 
      } 
      else{ 
       float floatedAverageDailyVolume = Float.valueOf(averageDailyVolume); 
       this.averageDailyVolume = (vf.format(floatedAverageDailyVolume)); 
      } 
     } 
     public String getPeRatio() { 
      return peRatio; 
     } 
     public void setPeRatio(String peRatio) { 
      if(peRatio.equals("null")) 
       this.peRatio = "N/A"; 
       else 
      this.peRatio = peRatio; 
     } 
     public String getMarketCapitalization() { 
      return marketCapitalization; 
     } 
     public void setMarketCapitalization(String marketCapitalization) { 
      if(marketCapitalization.equals("null")) 
       this.marketCapitalization = "N/A"; 
      else 
       this.marketCapitalization = marketCapitalization; 
     } 
     public String getYearHigh() { 
      return yearHigh; 
     } 
     public void setYearHigh(String yearHigh) { 
      if(yearHigh.equals("null")) 
       this.yearHigh = "N/A"; 
      else 
       this.yearHigh = yearHigh; 
     } 
     public String getYearLow() { 
      return yearLow; 
     } 
     public void setYearLow(String yearLow) { 
      if(yearLow.equals("null")) 
       this.yearLow = "N/A"; 
      else 
       this.yearLow = yearLow; 
     } 

     public String getLastTradePriceOnly() { 
      return lastTradePriceOnly; 
     } 

     public void setLastTradePriceOnly(String lastTradePriceOnly) { 
      if(lastTradePriceOnly.equals("null")){ 
       this.lastTradePriceOnly = "N/A"; 
      } 
      else{ 
       float floatedLastTradePriceOnly = Float.valueOf(lastTradePriceOnly); 
       this.lastTradePriceOnly = (df.format(floatedLastTradePriceOnly)); 
      } 
     } 

     @Override 
     public int hashCode() { 
      final int prime = 31; 
      int result = 1; 
      result = prime * result + ((change == null) ? 0 : change.hashCode()); 
      result = prime * result 
        + ((daysHigh == null) ? 0 : daysHigh.hashCode()); 
      result = prime * result + ((daysLow == null) ? 0 : daysLow.hashCode()); 
      result = prime 
        * result 
        + ((lastTradePriceOnly == null) ? 0 : lastTradePriceOnly 
          .hashCode()); 
      result = prime 
        * result 
        + ((marketCapitalization == null) ? 0 : marketCapitalization 
          .hashCode()); 
      result = prime * result + ((name == null) ? 0 : name.hashCode()); 
      result = prime * result + ((open == null) ? 0 : open.hashCode()); 
      result = prime * result + ((peRatio == null) ? 0 : peRatio.hashCode()); 
      result = prime * result 
        + ((percentChange == null) ? 0 : percentChange.hashCode()); 
      result = prime * result + ((symbol == null) ? 0 : symbol.hashCode()); 
      result = prime * result + ((volume == null) ? 0 : volume.hashCode()); 
      result = prime * result 
        + ((yearHigh == null) ? 0 : yearHigh.hashCode()); 
      result = prime * result + ((yearLow == null) ? 0 : yearLow.hashCode()); 
      return result; 
     } 
     @Override 
     public boolean equals(Object obj) { 
      if (this == obj) 
       return true; 
      if (obj == null) 
       return false; 
      if (getClass() != obj.getClass()) 
       return false; 
      Quote other = (Quote) obj; 
      if (change == null) { 
       if (other.change != null) 
        return false; 
      } else if (!change.equals(other.change)) 
       return false; 
      if (daysHigh == null) { 
       if (other.daysHigh != null) 
        return false; 
      } else if (!daysHigh.equals(other.daysHigh)) 
       return false; 
      if (daysLow == null) { 
       if (other.daysLow != null) 
        return false; 
      } else if (!daysLow.equals(other.daysLow)) 
       return false; 
      if (lastTradePriceOnly == null) { 
       if (other.lastTradePriceOnly != null) 
        return false; 
      } else if (!lastTradePriceOnly.equals(other.lastTradePriceOnly)) 
       return false; 
      if (marketCapitalization == null) { 
       if (other.marketCapitalization != null) 
        return false; 
      } else if (!marketCapitalization.equals(other.marketCapitalization)) 
       return false; 
      if (name == null) { 
       if (other.name != null) 
        return false; 
      } else if (!name.equals(other.name)) 
       return false; 
      if (open == null) { 
       if (other.open != null) 
        return false; 
      } else if (!open.equals(other.open)) 
       return false; 
      if (peRatio == null) { 
       if (other.peRatio != null) 
        return false; 
      } else if (!peRatio.equals(other.peRatio)) 
       return false; 
      if (percentChange == null) { 
       if (other.percentChange != null) 
        return false; 
      } else if (!percentChange.equals(other.percentChange)) 
       return false; 
      if (symbol == null) { 
       if (other.symbol != null) 
        return false; 
      } else if (!symbol.equals(other.symbol)) 
       return false; 
      if (volume == null) { 
       if (other.volume != null) 
        return false; 
      } else if (!volume.equals(other.volume)) 
       return false; 
      if (yearHigh == null) { 
       if (other.yearHigh != null) 
        return false; 
      } else if (!yearHigh.equals(other.yearHigh)) 
       return false; 
      if (yearLow == null) { 
       if (other.yearLow != null) 
        return false; 
      } else if (!yearLow.equals(other.yearLow)) 
       return false; 
      return true; 
     } 
    } 
+0

我真的很讨厌这样的类。类需要有真正的业务逻辑才值得 - 而我更喜欢沿着哈希线使用类似这样的东西。从长远来看,使用一个类作为一个属性包就会变得烦人。重复性应该表明它显然是错误的。有些人认为这是Java的错,我倾向于认为这是程序员不愿意分支出去的错。我已经以允许验证,类型安全和许多其他技巧的方式完成了这项工作。没有样板代码,但它有很多工作 - 尽管值得 - 样板很烂。 – 2010-09-13 22:25:28

+6

不知道我完全同意,但有一件事情对我来说是突出的:有所有这些setter和getter方法,但他们获取/设置的字段都是公开的!那些应该是私人的。 – 2010-09-13 22:44:05

回答

9

创建一个合适的Comparator,它将根据您所需的标准比较两个项目。然后在你的ArrayList上使用Collections.sort()

如果稍后您想按不同标准排序,请使用不同的Comparator再次拨打Collections.sort()

+0

你能提供一个我的compare()方法可能是什么样子的例子吗? – 2010-09-13 22:37:03

+0

@Sheehan该文档解释了合同。由您决定订购。想像它就像在图书馆看书,例如首先进入“小说”或“非小说类”部分,然后查找整个数字,然后查看小数点后的部分。你首先比较“更重要”的东西并不断缩小。如果一个更重要的部分多于另一个,则终止排序(因为您已经发现了更好的命令)。 – 2010-09-13 23:01:07

+0

这个答案不适用于我,我有两列,首先我想排序基于列之一arraylist之后,我想排序在第二列,但它不能正常工作,我arraylist排序列两totaly! “对于临时排序,一个单独的,可能是匿名的比较器更好。” – 2016-12-13 11:57:45

2

请参阅Collections.sort使用明确的比较器(或Collections.sort类型,需要输入以实现Comparable,如果您愿意的话)。

28

如果您(几乎)总是希望使用该订单,则可以将Comparable界面添加到报价并实施compareTo方法。

public int compareTo(Quote quote) { 
    int result = this.getName().compareTo(quote.getName()); 
    if (result == 0) { 
     result = this.getChange().compareTo(quote.getChange()); 
    } 
    if (result == 0) { 
     result = this.getPercentChange().compareTo(quote.getPercentChange()); 
    } 
    return result; 
} 

然后使用排序后的集合或对列表进行排序,然后对引号进行排序。

对于临时排序,单独的,可能是匿名的比较器更好。

+1

+1 – user3437460 2015-06-16 20:32:55

14

大家都很对,你想用比较器。扩展上的想法,如果你希望能够进行排序多个标准,那么像这样的类会为你工作:

public class MultiComparator<T> implements Comparator<T> { 
    private List<Comparator<T>> comparators; 

    public MultiComparator(List<Comparator<T>> comparators) { 
     this.comparators = comparators; 
    } 

    public int compare(T o1, T o2) { 
     for (Comparator<T> comparator : comparators) { 
      int comparison = comparator.compare(o1, o2); 
      if (comparison != 0) return comparison; 
     } 
     return 0; 
    } 
} 

然后你只需编写非常简单的比较无论哪个字段,你的愿望,你可以结合他们更容易更复杂的比较和更多的重用。

+0

如果需要进行大量比较和性能问题,可以将私有List >作为数组存储为数组Comparator [](它在构造方法中设置一次,永远不会更改,也不会读取由客户) - 至少使其最终。 – 2010-09-13 22:46:34

+0

同意,或者这个班可能是最终的。我差不多就是这么写的,以表达这个想法。在JDK中确实应该有类似的东西,如果它不在任何数量的集合库中,我会感到惊讶...... – romacafe 2010-09-13 23:01:06

+0

这种比较器链接的复杂性是什么?每次我们链接比较器时,我们是否基本上排序?所以我们为每个比较器做一个n * log(n)操作? – 2015-11-10 16:53:24

11

查看Apache Commons Collection的ComparatorChain。这应该完成这项工作。如果已经可用并经过测试,则不要实施逻辑。
在下面的网站我有一个教程:Sorting Objects By Multiple Attributes"

+0

+1 Thank you for this。不得不求助于第三方库,因为这是IMHO的一个Java编程语言的巨大缺点。我同意strangeoptics,不要在那里推出自己的实现是一个可以实现的库。直接链接到无依赖关系的ComparatorChain类:http://www.jarvana.com/jarvana/view/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1 -sources.jar!/org/apache/commons/collections/comparators/ComparatorChain.java – Moritz 2013-01-10 13:21:03

+0

谢谢您关闭提供示例代码来演示这个概念。这(与您的文章相结合)是OP问题的绝佳答案。 – 2017-01-30 17:05:55

相关问题