JB *_*zet 62
Collections.sort(listB, new Comparator<Item>() {
public int compare(Item left, Item right) {
return Integer.compare(listA.indexOf(left), listA.indexOf(right));
}
});
Run Code Online (Sandbox Code Playgroud)
但这是非常低效的,您应该创建一个Map<Item, Integer>from listA来更快地查找项目的位置.
Guava有一个现成的比较器来做到这一点: Ordering.explicit()
The*_*ech 40
Java 8:
Collections.sort(listToSort,
Comparator.comparing(item -> listWithOrder.indexOf(item)));
Run Code Online (Sandbox Code Playgroud)
或更好:
listToSort.sort(Comparator.comparingInt(listWithOrder::indexOf));
Run Code Online (Sandbox Code Playgroud)
rge*_*man 12
假设您有一个listB列表,用于定义要排序的顺序listA.这只是一个示例,但它演示了一个由列表定义的顺序,而不是数据类型的自然顺序:
List<String> listB = Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday");
Run Code Online (Sandbox Code Playgroud)
现在,让我们说listA需要根据这个顺序进行排序.这是一个List<Item>,并Item有一个public String getWeekday()方法.
创建一个Map<String, Integer>将所有内容的值映射listB到可以轻松排序的内容,例如索引,即"Sunday"=> 0,...,"Saturday"=> 6.这将提供快速简便的查找.
Map<String, Integer> weekdayOrder = new HashMap<String, Integer>();
for (int i = 0; i < listB.size(); i++)
{
String weekday = listB.get(i);
weekdayOrder.put(weekday, i);
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以创建Comparator<Item>使用Map创建订单的自定义:
public class ItemWeekdayComparator implements Comparator<Item>
{
private Map<String, Integer> sortOrder;
public ItemWeekdayComparator(Map<String, Integer> sortOrder)
{
this.sortOrder = sortOrder;
}
@Override
public int compare(Item i1, Item i2)
{
Integer weekdayPos1 = sortOrder.get(i1.getWeekday());
if (weekdayPos1 == null)
{
throw new IllegalArgumentException("Bad weekday encountered: " +
i1.getWeekday());
}
Integer weekdayPos2 = sortOrder.get(i2.getWeekday());
if (weekdayPos2 == null)
{
throw new IllegalArgumentException("Bad weekday encountered: " +
i2.getWeekday());
}
return weekdayPos1.compareTo(weekdayPos2);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以listA使用自定义排序Comparator.
Collections.sort(listA, new ItemWeekdayComparator(weekdayOrder));
Run Code Online (Sandbox Code Playgroud)
JB Nizet答案的速度提升(来自他自己提出的建议).用这种方法:
在我的单元测试中,对1000个项目列表进行100次排序可以提高速度10倍.
在我的单元测试中,对10000个项目列表进行100次排序可以将速度提高140倍(整个批次为265毫秒而不是37秒).
当两个列表不相同时,此方法也将起作用:
/**
* Sorts list objectsToOrder based on the order of orderedObjects.
*
* Make sure these objects have good equals() and hashCode() methods or
* that they reference the same objects.
*/
public static void sortList(List<?> objectsToOrder, List<?> orderedObjects) {
HashMap<Object, Integer> indexMap = new HashMap<>();
int index = 0;
for (Object object : orderedObjects) {
indexMap.put(object, index);
index++;
}
Collections.sort(objectsToOrder, new Comparator<Object>() {
public int compare(Object left, Object right) {
Integer leftIndex = indexMap.get(left);
Integer rightIndex = indexMap.get(right);
if (leftIndex == null) {
return -1;
}
if (rightIndex == null) {
return 1;
}
return Integer.compare(leftIndex, rightIndex);
}
});
}
Run Code Online (Sandbox Code Playgroud)
小智 7
问题:根据另一个列表中存在的字段的所有可能值之一对 Pojo 列表进行排序。
看看这个解决方案,可能这就是你想要实现的:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Employee> listToSort = new ArrayList<>();
listToSort.add(new Employee("a", "age11"));
listToSort.add(new Employee("c", "age33"));
listToSort.add(new Employee("b", "age22"));
listToSort.add(new Employee("a", "age111"));
listToSort.add(new Employee("c", "age3"));
listToSort.add(new Employee("b", "age2"));
listToSort.add(new Employee("a", "age1"));
List<String> listWithOrder = new ArrayList<>();
listWithOrder.add("a");
listWithOrder.add("b");
listWithOrder.add("c");
Collections.sort(listToSort, Comparator.comparing(item ->
listWithOrder.indexOf(item.getName())));
System.out.println(listToSort);
}
}
class Employee {
String name;
String age;
public Employee(String name, String age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
@Override
public String toString() {
return "[name=" + name + ", age=" + age + "]";
}
}
Run Code Online (Sandbox Code Playgroud)
输出 [[name=a, age=age11], [name=a,age=age111], [name=a,age=age1], [name=b,age=age22], [name=b,age=age2 ],[姓名=c,年龄=年龄33],[姓名=c,年龄=年龄3]]
这是一种解决方案,可以增加时间复杂度2n,但可以实现您想要的效果.它也不关心R您要排序的List 是否包含Comparable元素,只要L您用来对其进行排序的其他List 是统一的Comparable.
public class HeavyPair<L extends Comparable<L>, R> implements Comparable<HeavyPair<L, ?>> {
public final L left;
public final R right;
public HeavyPair(L left, R right) {
this.left = left;
this.right = right;
}
public compareTo(HeavyPair<L, ?> o) {
return this.left.compareTo(o.left);
}
public static <L extends Comparable<L>, R> List<R> sort(List<L> weights, List<R> toSort) {
assert(weights.size() == toSort.size());
List<R> output = new ArrayList<>(toSort.size());
List<HeavyPair<L, R>> workHorse = new ArrayList<>(toSort.size());
for(int i = 0; i < toSort.size(); i++) {
workHorse.add(new HeavyPair(weights.get(i), toSort.get(i)))
}
Collections.sort(workHorse);
for(int i = 0; i < workHorse.size(); i++) {
output.add(workHorse.get(i).right);
}
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
但请原谅我在编写此代码时使用的任何可怕做法.我匆匆忙忙.
打电话吧 HeavyPair.sort(listB, listA);
编辑:修正了这一行return this.left.compareTo(o.left);.现在它确实有效.
Khi*_*nsu -1
如果对象引用应该相同,则可以将listA初始化为新的。
listA = new ArrayList(listB)
Run Code Online (Sandbox Code Playgroud)