借助Guava Ordering,依据另一列表的比较器排序目标列表
解决方案
方法一:直接给listA传入关联listB的Comparator(注意重复元素限制)
如果listA中没有重复元素,可以通过元素索引关联listB,给listA.sort()传入自定义比较器:
// 基于已有的ordering,创建listA的比较器 Comparator<A> listAComparator = (a1, a2) -> { int idx1 = listA.indexOf(a1); int idx2 = listA.indexOf(a2); // 用listB对应位置的元素,通过ordering完成比较 return ordering.compare(listB.get(idx1), listB.get(idx2)); }; // 对listA原地排序 listA.sort(listAComparator);
注意:若listA存在重复元素,indexOf()会返回第一个匹配元素的索引,导致排序逻辑错误,这种场景建议用下面的方法。
方法二:通过索引排序重构listA(无重复问题,更可靠)
先对listB的索引进行排序,再根据排序后的索引重新排列listA,彻底避免重复元素带来的问题:
import com.google.common.collect.Lists; import com.google.common.primitives.Ints; // 生成0到listB长度-1的索引列表 List<Integer> indices = Ints.asList(Ints.range(0, listB.size())); // 根据listB对应元素的规则,对索引列表排序 List<Integer> sortedIndices = ordering.onResultOf(idx -> listB.get(idx)) .sortedCopy(indices); // 根据排序后的索引,生成排序后的listA List<A> sortedListA = Lists.transform(sortedIndices, idx -> listA.get(idx)); // 若需要原地修改原listA,清空后添加新元素 listA.clear(); listA.addAll(sortedListA);
关于Guava Ordering.explicit()的说明
Ordering.explicit()用于指定固定的元素顺序(比如你已经明确知道listB排序后的具体元素序列),如果你的场景是动态排序(比如字典序或自定义规则),用你已有的ordering = Ordering.from(new ComparatorB())就足够,不需要用到explicit()。
内容的提问来源于stack exchange,提问作者duplex143
相关产品推荐
相关产品推荐

