Java中使用Stream合并两个排序数组

Kee*_*thi 1 java arrays sorting algorithm java-stream

我有两个已排序的整数数组。我希望将它们合并到一个排序数组中。我想使用 Java Stream 来实现这一点。

我可以做一个嵌套流吗?

Arrays.asList(nums1).stream()
            .forEach(i -> Arrays.asList(nums2).stream()
                    .forEach(j -> //compare i,j)
                            .collect as list// ;  
Run Code Online (Sandbox Code Playgroud)

例如,[1,3,4]并且[2,5]应该返回[1,2,3,4,5]

Ale*_*nko 5

当我们sorted()在流管道上应用操作时,它会在内存中分配一个数组,该数组将填充流的元素并进行排序。

要对引用类型的数组进行排序,Java 使用Timsort 算法的实现,该算法擅长发现输入中已排序的数据块(Arrays.asList()您在示例中使用的需要 varargs T,所以我假设我们正在讨论对象)。

因此,如果我们简单地连接两个数据集,它仍然会表现得相当好。

String[] nums1 = {"1", "3", "4"};
String[] nums2 = {"2", "5"};
String[] merged = Stream.concat(Arrays.stream(nums1), Arrays.stream(nums2))
    .sorted()
    .toArray(String[]::new);
    
System.out.println(Arrays.toString(merged));
Run Code Online (Sandbox Code Playgroud)

输出:

[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

如果您想使用条件逻辑来获取排序的结果数组,那么您必须使用普通for循环。这不是流的工作。

使用命令式编程,可以这样实现:

String[] nums1 = {"1", "3", "4"};
String[] nums2 = {"2", "5"};

String[] merged = new String[nums1.length + nums2.length];
        
int pos1 = 0; // current index in the first array
int pos2 = 0; // current index in the second array

for (int i = 0; i < merged.length; i++) {
    if (pos2 >= nums2.length || pos1 < nums1.length // if the second array is exhausted or if both positions are valid and the current element in the first array is the lowest
        && nums1[pos1].compareTo(nums2[pos2]) < 0) {
        merged[i] = nums1[pos1++];
    } else {
        merged[i] = nums2[pos2++];
    }
}

System.out.println(Arrays.toString(merged));
Run Code Online (Sandbox Code Playgroud)

输出:

[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)