用Java中的几个比较器对列表进行排序的有效方法

leo*_*and 1 java sorting optimization performance

对不起我的英语不好.

我有这样的事情:

class SomeClass<T> {
    private List<T> elements;
    private List<Comparator<T>> comparators;

    public SomeClass(List<T> elements) {
        this.elements = elements;
        this.comparators = new ArrayList<Comparator<T>>();
    }

    public void addComparator(Comparator<T> comparator) {
        comparators.add(comparator);
    }

    public List<T> getSortedElements() {
        return sorted(new ArrayList<T>(elements));
    }

    // !!! At the moment I use very inefficient way
    // !!! to sort elements by several comparators.
    private List<T> sorted(List<T> toSort) {
        // I need to use stable sort.
        // Collections.sort(...) is guaranteed to be stable
        for (Comparator<T> comparator : comparators) {
            Collections.sort(toSort, comparator);
        }
        return toSort;
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以优化sorted() method吗?也许这可以通过使用组合比较器使用单一的集合排序来完成?(而不是每个比较器多次排序)

(但我必须使用稳定的排序,并且最后添加的比较器比开始时添加的比较器具有更高的优先级)

更新:

我使用几个比较器的排序来按不同的属性对元素进行排序(例如,按优先级,名称等)

Rad*_*def 6

问题在于,当您按照自己的方式对其进行排序时,后续排序会完全放弃先前排序所做的排序.

我认为你想要的是说"如果第一个比较器发现它们相等,则按下一个排序".你可以这样做:

class SomeClass<T> {
    private List<T> elements;
    private List<Comparator<T>> comparators;

    private final Comparator<T> combined = new Comparator<T>() {
        @Override
        public int compare(T e1, T e2) {
            for(Comparator<T> c : comparators) {
                int result = c.compare(e1, e2);

                if(result != 0)
                    return result;
            }

            return 0;
        }
    };

    ...

    private List<T> sorted(List<T> toSort) {
        Collections.sort(toSort, combined);

        return toSort;
    }
}
Run Code Online (Sandbox Code Playgroud)


gde*_*ohn 5

使用番石榴:

static <T> Comparator<T> compound(List<Comparator<T>> comparators)
{
    return Ordering.compound(comparators);
}
Run Code Online (Sandbox Code Playgroud)

给定一对元素,给定列表中的比较器依次尝试,直到一个产生非零结果,返回,或者没有比较器,在这种情况下返回零.