2010-09-13 14 views
7

Alıntı nesneleri içeren bir dizi listesi var. Alfabetik olarak isme, değişime ve yüzde değişime göre sıralamak istiyorum. Arraylistimi nasıl sıralayabilirim?Birden çok sıralama ölçütü kullanarak bir ArrayList nasıl sıralanır?

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

Gerçekten böyle derslerden nefret ediyorum. Sınıfların, değerinde olmak için gerçek iş mantığına sahip olması gerekir - Bunun gibi şeyler için karma çizgiler boyunca bir şey kullanmayı tercih ederim. Uzun vadede bir sınıfın bir öznitelik torbası olarak kullanılması can sıkıcı olur. Tekrarlama, açıkça yanlış olduğunu göstermelidir. Bazı insanlar bunu bir Java hatası olarak görüyor, ben daha çok programcıların ayrılmaya istekli olmamalarının bir hatası olduğunu düşünüyorum. Bunu doğrulama, tip güvenliği ve diğer birçok hileye izin veren şekillerde yaptım. Boilerplate kodu yok ama iş çok oldu - iyi değer olsa da - kiremit berbat. –

+6

Tamamen aynı fikirdeyim ama bir şey benim için önemli değil: Tüm bu belirleyici ve alıcı yöntemler var, ama aldıkları/aldıkları alanlar herkese açık! Bunlar özel olmalı. –

cevap

9

İki maddeyi istediğiniz ölçütlere göre karşılaştıracak bir Comparator uygun oluşturun. ArrayList öğenizde Collections.sort() kullanın.

Daha sonraki bir zamanda farklı ölçütlere göre sıralamak isterseniz, Collections.sort() numaralı telefonu tekrar farklı bir Comparator ile arayın.

+0

Compare compare() yönteminin neye benzeyebileceğine dair bir örnek verebilir misiniz? –

+0

@Sheehan Belgeler sözleşmeyi açıklar. Siparişi belirlemek size kalmıştır. Bunu kitaplıktaki bir kitaba bakmak gibi düşünün, ör. önce "Kurgu" ya da "Kurgu Olmayan" bölümüne gidersiniz, sonra tam sayıya bakarsınız, sonra ondalık kısımdan sonra ... ör. önce "daha önemli" şeyleri karşılaştırır ve daraltmaya devam eder.Daha önemli bir kısım diğerinden daha fazlaysa, siparişi sonlandırır (zaten daha iyi olan siparişi bulduğunuz gibi). –

+0

Bu cevap benim için işe yaramıyor, iki sütun var, ilk önce sütunlara göre arraylistleri sıralamak istiyorum, sonra iki sütun üzerinde sıralamak istiyorum, ama düzgün çalışmıyor ve arraylist iki sütunta sıralı olarak dizildi! –

2

Collections.sort açık bir Karşılaştırıcı ile (veya tercih ederseniz, Comparable değerini uygulamak için girdiyi gerektiren Koleksiyonlar.sort türüne bakın).

28

Eğer (hemen hemen) her zaman bu sırayı kullanmak isterseniz, Karşılaştırma arabirimini Teklif'e ekleyebilir ve bir compareTo yöntemi uygulayabilirsiniz.

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; 
} 

Sonra sıralama yapıldığını koleksiyonunu kullanın veya bir liste sıralamak ve tırnak sıralanacaktır.

Ad hoc sorting için ayrı, muhtemelen anonim, Karşılaştırıcı daha iyidir.

+1

için "Ad hoc sorting için ayrı, muhtemelen anonim, Karşılaştırıcı daha iyidir." +1 – user3437460

14

Karşılaştırıcıları kullanmak istediğiniz herkes haklıdır. hangisi için arzu alanları

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; 
    } 
} 

Sonra sadece gerçekten basit karşılaştırıcılara yazmak ve birleştirebilirsiniz: Birden kriterlere sıralamak mümkün istiyorum eğer, fikri üzerine genişletilmesi sonra böyle bir sınıf sizin için çalışacaktır Onları daha karmaşık karşılaştırıcılara daha kolay ve daha fazla yeniden kullanma ile.

+0

Yapılması gereken çok fazla karşılaştırma varsa ve performans bir sorunsa, özel Liste > bir dizi Karşılaştırıcı [] olarak saklanabilir (kurucuda bir kez ayarlanır, hiçbir zaman değiştirilmez ve hiç okunmaz Müşteriler tarafından) - en azından son haline getirin. –

+0

Anlaşıldı, ya da belki de sınıf final olabilir. Ben bu fikri göstermek için neredeyse o kadar soğuk yazdım. JDK'da bir tür gerçekten olmalıydı ve eğer herhangi bir sayıda koleksiyon kütüphanesinde olmasaydı şaşıracaktım ... – romacafe

+0

Karşılaştırıcıların bu tür zincirlemelerinin karmaşıklığı ne olurdu? Karşılaştırıcıları zincirlediğimiz her zaman esasen sıralanıyor muyuz? Yani her bir karşılaştırıcı için n * log (n) işlemi yapıyoruz? –

11

Apache Commons Collection'dan ComparatorChain'e bir göz atın. Bu işi yapmalı. Zaten mevcut ve test edilmişse mantığı uygulama.
Aşağıdaki sitede bir dersim var: Sorting Objects By Multiple Attributes"

+0

+1 Bunun için teşekkür ederiz. Bunun için bir üçüncü parti kütüphanesine başvurmak, Java programlama dilinin büyük bir eksikliğidir IMHO, strangeoptics ile aynı fikirdeyim. bağımlılık yapıcı bir ComplorerChain sınıfına doğrudan bağlantı: 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

+0

Teşekkür ederiz kavramını göstermek için örnek kod. Bu (makalenizle birlikte) OP sorusuna mükemmel bir cevaptır. –

İlgili konular