java 基于可配置顺序的比较器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5477511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:18:02  来源:igfitidea点击:

Comparator based on a configurable order

java

提问by London

Is there a way to write custom comparator, following this example:

有没有办法编写自定义比较器,请遵循以下示例:

There are at most 10 items coming in at a random order i.e.

最多有 10 个项目以随机顺序进入,即

first item:  item_one
second:      second_one
third:       third_one

I want result them to be sorted like : second_one, third_one, first_one. I'd like to pull this order from configuration file, sort of like template for sorting.

我希望结果它们被排序为 : second_one, third_one, first_one。我想从配置文件中提取这个订单,有点像用于排序的模板。

Am I using the wrong data structure, does anyone have experience with this?

我是否使用了错误的数据结构,有人有这方面的经验吗?

回答by aioobe

Sure. Here is an "OrderedComparator" that compares elements according to a predefined order:

当然。这是一个“ OrderedComparator”,它根据预定义的顺序比较元素:

class OrderedComparator implements Comparator<String> {

    List<String> predefinedOrder;

    public OrderedComparator(String[] predefinedOrder) {
        this.predefinedOrder = Arrays.asList(predefinedOrder);
    }

    @Override
    public int compare(String o1, String o2) {
        return predefinedOrder.indexOf(o1) - predefinedOrder.indexOf(o2);
    }

}

And here is some test code. (I used a Listinstead of a Setsince it 1) seem more natural when talking about the order of the elements and 2) better illustrate what happens with duplicate elements upon sorting using this comparator.)

这是一些测试代码。(我使用 aList而不是 a,Set因为它 1)在谈论元素的顺序时看起来更自然,2)更好地说明在使用此比较器进行排序时重复元素会发生什么。)

class Test {

    public static void main(String[] args) {

        // Order (could be read from config file)
        String[] order = { "lorem", "ipsum", "dolor", "sit" };


        List<String> someList = new ArrayList<String>();

        // Insert elements in random order.
        someList.add("sit");
        someList.add("ipsum");
        someList.add("sit");
        someList.add("lorem");
        someList.add("dolor");
        someList.add("lorem");
        someList.add("ipsum");
        someList.add("lorem");


        System.out.println(someList);

        Collections.sort(someList, new OrderedComparator(order));

        System.out.println(someList);
    }

}

Output:

输出:

[sit, ipsum, sit, lorem, dolor, lorem, ipsum, lorem]
[lorem, lorem, lorem, ipsum, ipsum, dolor, sit, sit]

回答by David Soroko

Take a look at TreeSet (http://download.oracle.com/javase/6/docs/api/java/util/TreeSet.html). You can provide a custom Comparator in a constructor. This Comparator will take into account your config. file . The logic of the comparator will not be pretty though since you want arbitrary order. You will most probably end up enumerating all possible comparisons.

看看 TreeSet (http://download.oracle.com/javase/6/docs/api/java/util/TreeSet.html)。您可以在构造函数中提供自定义 Comparator。此比较器将考虑您的配置。文件 。由于您想要任意顺序,因此比较器的逻辑不会很漂亮。您很可能最终会枚举所有可能的比较。

回答by Jonathan

A set stores unordered elements. If you want to compare and sort, you should probably go with a list. Here's a quick snippet for you:

集合存储无序元素。如果你想比较和排序,你可能应该使用一个列表。这是给你的一个快速片段:

List<X> sorted = new ArrayList<X>(myset);
Collections.sort(sorted, new Comparator<X>() {
    public int compare(X o1, X o2) {
        if (/* o1 < o2 */) {
            return -1;
        } else if (/* o1 > o2 */) {
            return 1;
        } else {
            return 0;
        }
    }
});

Now you've got sorted, which has all the same elements of myset, which was unordered by virtue of being a set.

现在你得到了sorted,它具有 的所有相同元素myset,由于是一个集合,它是无序的。

You can also look at TreeSet, which orders its elements, but it's generally not a good idea to rely on a set being ordered.

您还可以查看TreeSet, 它对其元素进行排序,但依赖被排序的集合通常不是一个好主意。

回答by Andrew Ko

Use Guava's com.google.common.collect.Ordering:

使用 Guava 的 com.google.common.collect.Ordering:

Ordering.explicit(second_one, third_one, first_one);