按多个属性对列表进行排序

时间:2016-05-24 18:24:01

标签: java sorting collections comparator

  • 我有一些食谱对象,包含不同的属性,如季节,地区,类别(所有字符串)

  • 有一本食谱,包含食谱清单。该cookbook还有一个Attribute sortLevelChain(String)。

  • sortLevelChain指定,我想通过仅将Recipe属性名称与点连接(例如“Season.Region.Category”)来对列表中包含的食谱进行排序。

现在我需要一个解决方案来解决如何按照sortLevelChain指定的方式对List进行排序。我找到了Apaches ComparatorChain,但我不知道如何使用它。欢迎每个工作解决方案=)

2 个答案:

答案 0 :(得分:1)

实施很简单。希望下面的示例有帮助。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.collections.comparators.ComparatorChain;

public class ComparatorChainTest {

    public static void main(String[] args){

        ComparatorChain comparatorChain = new ComparatorChain();
        String[] filters = "Season.Region.Category".split(".");
        Comparator comparator = null;
        for(String filter:filters){

            if("season".equalsIgnoreCase(filter)){
                comparator = new Comparator<Recipe>() {
                    @Override
                    public int compare(Recipe o1, Recipe o2) {
                        return o1.getSeason().compareTo(o2.getSeason());
                    }
                };
            }
            if("region".equalsIgnoreCase(filter)){
                comparator = new Comparator<Recipe>() {
                    @Override
                    public int compare(Recipe o1, Recipe o2) {
                        return o1.getRegion().compareTo(o2.getRegion());
                    }
                };
            }
            if("category".equalsIgnoreCase(filter)){
                comparator = new Comparator<Recipe>() {
                    @Override
                    public int compare(Recipe o1, Recipe o2) {
                        return o1.getCategory().compareTo(o2.getCategory());
                    }
                };
            }
            comparatorChain.addComparator(comparator);
        }
        List<Recipe> recipes = new ArrayList<Recipe>();
        Collections.sort(recipes,comparatorChain);
    }

    public class Recipe{
        private String season;
        private String region;
        private String category;
        public String getSeason() {
            return season;
        }
        public void setSeason(String season) {
            this.season = season;
        }
        public String getRegion() {
            return region;
        }
        public void setRegion(String region) {
            this.region = region;
        }
        public String getCategory() {
            return category;
        }
        public void setCategory(String category) {
            this.category = category;
        }
    }
}

答案 1 :(得分:0)

这里有几种可能性。对于Apache ComparatorChain,请阅读documentation。您必须为所需的每个订单实施比较器,此处为SeasonComparatorRegionComparatorCategoryComparator

对于ComparatorChain,实例化它并一个接一个地添加比较器:

ComparatorChain<Recipe> chain = new ComparatorChain<>();

for (String elt : sortLevelChain.split("\.")) {
    if (elt.equals("Season"))        chain.addComparator(new SeasonComparator());
    else if (elt.equals("Region"))   chain.addComparator(new RegionComparator());
    else if (elt.equals("Category")) chain.addComparator(new CategoryComparator());
    else throw new IllegalArgumentException("Comparator not supported");
}

Collections.sort(recipeList, chain);

使用非常简单,但如果您经常需要这种链式比较器,则可以优化此方法。