Reputation: 15274
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
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.
Am I using the wrong data structure, does anyone have experience with this?
Upvotes: 14
Views: 19937
Reputation: 301
Use Guava's com.google.common.collect.Ordering:
Ordering.explicit(second_one, third_one, first_one);
Upvotes: 0
Reputation: 421090
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]
Upvotes: 19
Reputation: 13624
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.
Upvotes: 1
Reputation: 9096
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.
Upvotes: 2