How to sort an ArrayList using multiple sorting criteria?

孤街浪徒 提交于 2019-12-27 10:40:48

问题


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

回答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.




回答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.




回答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.




回答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"




回答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.




回答6:


See Collections.sort with an explicit Comparator (or the Collections.sort kind that requires the input to implement Comparable, if you prefer).




回答7:


There are two things:

  1. Sorting on multiple fields of an object
  2. Multilevel sorting (Here sorting done on first field and then next sorting applied on grouping done on similar items in previous sort)

For #2: I found this below article very much close to what i desire http://strangeoptics.blogspot.com/2011/09/sorting-objects-by-multiple-attributes.html



来源:https://stackoverflow.com/questions/3704804/how-to-sort-an-arraylist-using-multiple-sorting-criteria

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!