首页 > 解决方案 > 在更新 Comparator 比较函数的计数时返回列表的索引

问题描述

我正在使用另一个列表对一个列表进行排序。排序的目的是,如果数组包含这些元素,则将数组 B 中存在的元素带到数组 A 的顶部。

例如:

inputA = {"A", "B", "G"} inputB = {"G", "F"} output should be A = {"G", "A", "B"}

我的排序代码如下所示

Collections.sort( inputA, 
           Comparator.comparing( a -> inputB.indexOf( a ) > -1 ? -1 : a.getIndex()));

我真正的代码不是这个,但想法是一样的。真实代码包含两个带有复杂对象的通用列表。

我的排序代码工作正常。我想做的是在返回时,-1或者a.getIndex(),我想获取-1返回的 no.of 的计数。

我怎样才能在这段代码中做到这一点?有什么建议么?

更新

inputA = {"A", "B", "C", "G"} inputB = {"G", "B"} output should be A = {"B", "G", "A", "C"}

我得到的输出是 output = {"B", "G", "C", "A"}

在原始inputA元素中,“C”在元素“A”之后。但在我的结果中,我以相反的顺序得到它。

我怎样才能解决这个问题?

a.getIndex()返回一个包含原始顺序的整数。似乎比较器没有使用它对其进行排序。

标签: javalambdajava-streamcomparatorindexof

解决方案


这种a.getIndex()表达方式导致了错误的方向。排序操作保证是稳定的,这意味着根据比较器相等的元素不会改变它们的相对顺序。

所以如果你有

List<String> inputA = Arrays.asList("A", "B", "G");
List<String> inputB = Arrays.asList("G", "F");

并使用

inputA.sort(Comparator.comparing(inputB::contains).reversed());

你会得到订单[G, A, B]

同样地,

List<String> inputA = Arrays.asList("A", "B", "C", "G");
List<String> inputB = Arrays.asList("G", "B");

inputA.sort(Comparator.comparing(inputB::contains).reversed());

会导致[B, G, A, C]。由于提供的比较器的唯一标准是元素是否包含在另一个列表中,因此两组中每个组(“包含”和“不包含”)中元素的相对顺序不会改变。

请注意,如果listB相当大,重复的线性搜索可能会导致性能问题。这可以通过使用临时哈希集进行快速查找来解决:

inputA.sort(Comparator.comparing(new HashSet<>(inputB)::contains).reversed());

推荐阅读