我有一个带有方法getPriority()的对象列表,它返回字符串中的对象优先级,以及返回对象名称(也是字符串)的方法getName()。我有一个列表,' priority',其中包含类似' high' '介质'和'低'。
我想按顺序列表中getPriority()方法的位置来排序对象列表,对于具有相同优先级或没有优先级的对象,然后根据名称按字母顺序排序。
例如:
List<MyObject> objects = new ArrayList<MyObject>();
objects.add(new MyObject("apple", "low"));
objects.add(new MyObject("bacon", "medium"));
objects.add(new MyObject("cheese", "low"));
objects.add(new MyObject("doughnut", "high"));
objects.add(new MyObject("eggs", null));
objects.add(new MyObject("fudge", null));
List<String> priority = new ArrayList<String>();
priority.add("high");
priority.add("medium");
priority.add("low");
将分类为:甜甜圈,培根,苹果,奶酪,鸡蛋,软糖。
重要的是不要使用枚举作为优先级,因为它需要由最终用户自定义。它还需要接受空优先级,因为从数据库中获取优先级,如果在数据库中找不到对象仍然需要进行排序。
答案 0 :(得分:2)
添加一个新的比较器类来对对象进行排序,定义如下:
class MyObjectPrioritizer extends Comparator<MyObject> {
List<String> priority;
MyObjectPrioritizer(List<String> priorityOrder) {
priority = priorityOrder;
}
public int compare(MyObject o1, MyObject o2) {
int v1 = resolveValue(o1);
int v2 = resolveValue(o2);
return v1 - v2;
}
int resolveValue(MyObject o) {
int sort = priority.indexOf(o.priority));
// put null & unknown values at the end
if (sort == -1) sort = Integer.MAX_VALUE;
return sort;
}
}
然后只是:
Collections.sort(objects, new MyObjectPrioritizer(priority));
答案 1 :(得分:1)
您可以使用比较器对列表进行排序。 e.g:
<强>代码强>:
List<MyObject> objects = new ArrayList<MyObject>();
objects.add(new MyObject("apple", "low"));
objects.add(new MyObject("bacon", "medium"));
objects.add(new MyObject("cheese", "low"));
objects.add(new MyObject("doughnut", "high"));
objects.add(new MyObject("eggs", null));
objects.add(new MyObject("fudge", null));
final List<String> priority = new ArrayList<String>();
priority.add("high");
priority.add("medium");
priority.add("low");
Comparator<MyObject> comparator = new Comparator<MyObject>() {
public int compare(MyObject o1, MyObject o2) {
int p1 = priority.indexOf(o1.getPriority());
int p2 = priority.indexOf(o2.getPriority());
if (p1 == -1 && p2 != -1) {
return 1;
}
if (p1 != -1 && p2 == -1) {
return -1;
}
if (p1 != p2) {
return p1 - p2;
}
return o1.getName().compareTo(o2.getName());
}
};
Collections.sort(objects, comparator);
for(MyObject obj : objects) {
System.out.printf("%-10s %10s%n", obj.getName(), obj.getPriority());
}
<强>输出强>:
doughnut high
bacon medium
apple low
cheese low
eggs null
fudge null
答案 2 :(得分:0)
我建议使用Guava Ordering。
使用Ordering.explicit
可以让我们按照它们在列表中显示的顺序进行比较。
为了按优先级排序对象按名称排序,这两个排序与Ordering.thenComparing
一起组成。
// Sorts MyObject by name
public static final Ordering<MyObject> MY_OBJECT_FOOD_ORDERING = new Ordering<MyObject>() {
@Override
public int compare(final MyObject left, final MyObject right) {
return ComparisonChain.start()
.compare(left == null ? null : left.getName(), right == null ? null : right.getName())
.result();
}
};
public static final Ordering<MyObject> buildPriorityOrdering(final List<String> priorities) {
return buildPriorityOrdering(Ordering.explicit(ImmutableList.<String> builder()
.addAll(priorities)
.build())
.nullsLast());
}
public static final Ordering<MyObject> buildPriorityOrdering(final Ordering<String> priorityOrdering) {
return new Ordering<ListOrdering.MyObject>() {
@Override
public int compare(final MyObject left, final MyObject right) {
return ComparisonChain.start()
.compare(left == null ? null : left.getPriority(), right == null ? null : right.getPriority(),
priorityOrdering)
.result();
}
};
}
public static void main(final String... args) {
final List<String> priorities = ImmutableList.<String> builder()
.add("high")
.add("medium")
.add("low")
.build();
final List<MyObject> myObjects = ImmutableList.<MyObject> builder()
.add(new MyObject("doughnut", "high"))
.add(new MyObject("cheese", "low"))
.add(new MyObject("eggs", null))
.add(new MyObject("apple", "low"))
.add(new MyObject("fudge", null))
.add(new MyObject("bacon", "medium"))
.build();
final List<MyObject> myObjectsSorted = FluentIterable.from(myObjects)
.toSortedList(buildPriorityOrdering(priorities).thenComparing(MY_OBJECT_FOOD_ORDERING));
/*
* Results:
* MyObject [name=doughnut, priority=high]
* MyObject [name=bacon, priority=medium]
* MyObject [name=apple, priority=low]
* MyObject [name=cheese, priority=low]
* MyObject [name=eggs, priority=null]
* MyObject [name=fudge, priority=null]
*/
System.out.println(Joiner.on("\n")
.join(myObjectsSorted));
}
public static class MyObject {
private final String name;
private final String priority;
public MyObject(final String name, final String priority) {
this.name = name;
this.priority = priority;
}
public String getName() {
return this.name;
}
public String getPriority() {
return this.priority;
}
@Override
public String toString() {
return "MyObject [name=" + this.name + ", priority=" + this.priority + "]";
}
}
感谢@Barett的 nullsFirst nullsLast