更新比较器比较功能的计数时返回列表的索引

时间:2019-02-05 03:37:16

标签: java lambda java-stream comparator indexof

我正在使用另一个列表对一个列表进行排序。排序的目的是,如果数组B中存在的元素包含在数组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()));

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

我的排序代码正常工作。我想做的是,当我返回-1a.getIndex()时,我想获得返回的-1的数量。

如何在此代码中执行此操作?有什么建议吗?

更新

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()返回一个包含原始顺序的整数。似乎比较器没有使用它对它进行排序。

4 个答案:

答案 0 :(得分:1)

您可以保留一个计数器,该计数器在每次返回-1时都会增加。这是您修改的代码:

AtomicInteger count = new AtomicInteger(0);
Collections.sort(a, Comparator.comparing(s -> {
    if (b.indexOf(s) > -1) {
        count.incrementAndGet();
        return -1;
    }
    return a.indexOf(s);
}));
System.out.println(count.get());

答案 1 :(得分:1)

这个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());

答案 2 :(得分:0)

据我所知,-1的数量等于inputAinputB的交点的大小。您可以使用以下代码段获取此值:

var distinctB = Set.copyOf(inputB);
long commonSize = inputA.stream().filter(distinctB::contains).count();

这假设inputAinputB是一些Collection(您说过通用列表)。

答案 3 :(得分:0)

类似的事情应该做:

Vector<String> inputA = new Vector();
Vector<String> inputB = new Vector();
// fill elements/ get userelements 
// ...

//push to front:
for(String element:inputB){
    if(inputA.remove(element)){
        inputA.add(0, element);
    }
}

一些链表作为容器应该性能更高。阵列将有大量复制-不是最佳选择。但是容器的选择取决于您...