Como classificar um ArrayList usando vários critérios de sorting?

Eu tenho uma lista de matriz que contém objects Quote. Eu quero ser capaz de classificar em ordem alfabética por nome, por alteração e por alteração percentual. Como posso classificar meu 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; } } 

Crie um Comparator apropriado que compare dois itens de acordo com os critérios desejados. Em seguida, use Collections.sort() em sua ArrayList.

Se, posteriormente, você quiser classificar por critérios diferentes, chame Collections.sort() novamente com um Comparator diferente.

Se você (quase) sempre quiser usar essa ordem, poderá adicionar a interface Comparable a Quote e implementar um método 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; } 

Em seguida, use uma coleção classificada ou classifique uma lista, e as cotações serão classificadas.

Para sorting ad hoc, um Comparador separado, possivelmente anônimo, é melhor.

Todo mundo está certo que você quer usar Comparadores. Com base nessa ideia, se você quiser classificar vários critérios, uma class como essa funcionará para você:

 public class MultiComparator implements Comparator { private List> comparators; public MultiComparator(List> comparators) { this.comparators = comparators; } public int compare(T o1, T o2) { for (Comparator comparator : comparators) { int comparison = comparator.compare(o1, o2); if (comparison != 0) return comparison; } return 0; } } 

Então você apenas escreve comparadores realmente simples para os campos que desejar e pode combiná-los em comparadores mais complexos com mais facilidade e com mais reutilização.

Dê uma olhada no ComparatorChain da Apache Commons Collection. Isso deve fazer o trabalho. Não implemente lógica se já estiver disponível e testado.
No site a seguir, tenho um tutorial: Classificando Objetos por Vários Atributos ”

A Sun dedicou grande parte de seu tutorial à sorting em collections Java:
http://download.oracle.com/javase/tutorial/collections/interfaces/order.html

Ele discute as interfaces Comparable e Comparator com exemplos.

Veja Collections.sort com um Comparador explícito (ou o tipo Collections.sort que requer a input para implementar o Comparable , se você preferir).