2010-09-13 184 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

相關問題