我正在使用另一个列表对一个列表进行排序。排序的目的是,如果数组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()));
我真正的代码不是这个,但是想法是一样的。实际代码包含两个带有复杂对象的通用列表。
我的排序代码正常工作。我想做的是,当我返回-1
或a.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()
返回一个包含原始顺序的整数。似乎比较器没有使用它对它进行排序。
答案 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
的数量等于inputA
和inputB
的交点的大小。您可以使用以下代码段获取此值:
var distinctB = Set.copyOf(inputB);
long commonSize = inputA.stream().filter(distinctB::contains).count();
这假设inputA
和inputB
是一些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);
}
}
一些链表作为容器应该性能更高。阵列将有大量复制-不是最佳选择。但是容器的选择取决于您...