Comparator based on a configurable order

后端 未结 4 1498
一生所求
一生所求 2020-12-09 11:33

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.

first item:  item_one         


        
相关标签:
4条回答
  • 2020-12-09 12:01

    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.

    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.

    0 讨论(0)
  • 2020-12-09 12:08

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

    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 List instead of a Set since 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.)

    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]
    
    0 讨论(0)
  • 2020-12-09 12:13

    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.

    0 讨论(0)
  • 2020-12-09 12:17

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

    Ordering.explicit(second_one, third_one, first_one);
    
    0 讨论(0)
提交回复
热议问题