How to sort an ArrayList using multiple sorting criteria?
Solution 1
Create an appropiate Comparator
that will compare two items according to your desired criteria. Then use Collections.sort()
on your ArrayList.
If at a later time you want to sort by different criteria, call Collections.sort()
again with a different Comparator
.
Solution 2
If you (almost) always want to use that order you can add the Comparable interface to Quote and implement a compareTo method.
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;
}
Then use a sorted collection, or sort a list, and the quotes will be sorted.
For ad hoc sorting, a separate, possibly anonymous, Comparator is better.
Solution 3
Everybody is right that you want to use Comparators. Extending on that idea, if you want to be able to sort on multiple criteria, then a class like this will work for you:
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;
}
}
Then you just write really simple comparators for whichever fields you desire and you can combine them into more complex comparators more easily and with more reuse.
Solution 4
Have a look at the ComparatorChain from the Apache Commons Collection. This should do the job. Don't implement logic if is already available and tested.
At the following site I have a tutorial: Sorting Objects By Multiple Attributes"
Solution 5
Sun has devoted big part of its tutorial to sorting in Java collections:
http://download.oracle.com/javase/tutorial/collections/interfaces/order.html
It discusses both Comparable and Comparator interfaces with examples.
Sheehan Alam
iOS, Android and Mac Developer. i can divide by zero.
Updated on July 09, 2022Comments
-
Sheehan Alam almost 2 years
I have an array list that contains Quote objects. I want to be able to sort alphabetically by name, by change, and by percent change. How can I sort my 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; } }