按另一个列表排序列表元素。

huangapple go评论79阅读模式
英文:

Sort list elements by another list

问题

我有两个列表 A[1,2,4,5,6,7,8,9]B[6,3,8,2]。我需要按照 B 列表的索引对 A 列表进行排序,以便 A 列表变为 [6,8,2,1,4,5,7,9]。有没有一种有效的方法可以实现这个目标?

尝试使用 Java 8 的流和比较器:

listB.sort(Comparator.comparingInt(element -> listA.indexOf(element)));

但是因为 listB 并不包含 listA 的所有元素,所以会出现 UnsupportedOperationException 异常。

英文:

I have two lists A[1,2,4,5,6,7,8,9] and B[6,3,8,2]. I need to sort the A list by B list indexes. So that the A list will be [6,8,2,1,4,5,7,9]. Is there any efficient way to do that?

Tried using java8 streaming and comparators

listB.sort(Comparator.comparingInt(element -> listA.indexOf(element)));

But was getting UnsupportedOperationException as listB doesn't have all elements of listA.

答案1

得分: 0

List.indexOf如果元素不存在,不会抛出UnsupportedOperationException,而是返回-1。因此,您只需确保索引为-1会导致“在末尾的某个位置”,即一个较高的数字(例如列表大小或Integer.MAX_VALUE)。

如果您收到UnsupportedOperationException,很可能是因为listB不可变,因此不支持原地排序。

英文:

List.indexOf doesn't throw UnsupportedOperationException if the element isn't there, it returns -1. So all you need to do is make sure that an index of -1 will result in "somewhere at the end", meaning a high number (such as the list size or Integer.MAX_VALUE.

If you are getting an UnsupportedOperationException, it's most likely because listB isn't mutable, so it won't support sorting in-place.

答案2

得分: 0

为了提高性能,可以首先将listB中所有元素的索引存储在一个Map中。然后,为了将不在listB中的元素排序到结果的末尾,可以给它们的排序键都设置为Integer.MAX_VALUE

var listA = Arrays.asList(1,2,4,5,6,7,8,9);
var listB = List.of(6,3,8,2);
var index = IntStream.range(0, listB.size()).boxed()
                     .collect(Collectors.toMap(listB::get, i -> i));
listA.sort(Comparator.comparingInt(x -> index.getOrDefault(x, Integer.MAX_VALUE)));
// listA = [6, 8, 2, 1, 4, 5, 7, 9]
英文:

To improve performance, the indexes of all the elements in listB can be stored in a Map first. Then, to order elements that are not in listB to the end of the result, they can all be given Integer.MAX_VALUE as the sort key.

var listA = Arrays.asList(1,2,4,5,6,7,8,9);
var listB = List.of(6,3,8,2);
var index = IntStream.range(0, listB.size()).boxed()
                     .collect(Collectors.toMap(listB::get, i -> i));
listA.sort(Comparator.comparingInt(x -> index.getOrDefault(x, Integer.MAX_VALUE)));
// listA = [6, 8, 2, 1, 4, 5, 7, 9]

huangapple
  • 本文由 发表于 2023年7月20日 20:10:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76729712.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定