英文:
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]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论