使用流合并两个排序的阵列在Java中

发布于 2025-02-06 06:51:09 字数 373 浏览 1 评论 0原文

我有两个排序的整数阵列。我希望将它们合并为一个排序的阵列。我想使用Java流来实现这一目标。

我可以做一个嵌套的流吗?

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

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

I have two sorted integer arrays. I am looking to merge them into one sorted array. I would like to use Java Stream to achieve this.

Can I do a nested stream?

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

For example, [1,3,4] and [2,5] should return [1,2,3,4,5]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凑诗 2025-02-13 06:51:10
Integer [] arrOne = {1,3,40};
Integer [] arrTwo = {44,6,7};

private Integer[] flatTwoArray(Integer[] aa, Integer[] ab) {
    return Stream.of(aa,ab).flatMap(Stream::of).sorted().toArray(Integer[]::new);
Integer [] arrOne = {1,3,40};
Integer [] arrTwo = {44,6,7};

private Integer[] flatTwoArray(Integer[] aa, Integer[] ab) {
    return Stream.of(aa,ab).flatMap(Stream::of).sorted().toArray(Integer[]::new);
寄风 2025-02-13 06:51:10

在我的解决方案下方,o(n)的复杂时间

private int[] merge2SortedArrays(int[] arr1, int[] arr2) {
    int arr1Length = arr1.length;
    int arr2Length = arr2.length;
    int arr1Index = 0;
    int arr2Index = 0;
    int maxLength = Math.max(arr1Length, arr2Length);
    int[] merge2SortedArray = new int[arr1Length + arr2Length];
    int lastIndexMergeArray = 0;
    for (int i = 0; i < maxLength; i++, lastIndexMergeArray++) {
        int valueArr1 = arr1[arr1Index];
        int valueArr2 = arr2[arr2Index];
        if (valueArr1 < valueArr2) {
            merge2SortedArray[lastIndexMergeArray] = valueArr1;
            arr1Index++;
        } else if (valueArr1 > valueArr2) {
            merge2SortedArray[lastIndexMergeArray] = valueArr2;
            arr2Index++;
        } else {
            merge2SortedArray[lastIndexMergeArray] = valueArr1;
            lastIndexMergeArray++;
            merge2SortedArray[lastIndexMergeArray] = valueArr2;
            arr1Index++;
            arr2Index++;
        }
    }

    addLeftValues(arr1, arr1Index, merge2SortedArray, lastIndexMergeArray);
    addLeftValues(arr2, arr2Index, merge2SortedArray, lastIndexMergeArray);
    return merge2SortedArray;
}

private static void addLeftValues(int[] arr, int arrIndex, int[] merge2SortedArray, int lastIndexMergeArray) {
    for (int i = arrIndex; i < arr.length; i++) {
        merge2SortedArray[lastIndexMergeArray] = arr[i];
    }
}

Below my solution with complexity time of O(n)

private int[] merge2SortedArrays(int[] arr1, int[] arr2) {
    int arr1Length = arr1.length;
    int arr2Length = arr2.length;
    int arr1Index = 0;
    int arr2Index = 0;
    int maxLength = Math.max(arr1Length, arr2Length);
    int[] merge2SortedArray = new int[arr1Length + arr2Length];
    int lastIndexMergeArray = 0;
    for (int i = 0; i < maxLength; i++, lastIndexMergeArray++) {
        int valueArr1 = arr1[arr1Index];
        int valueArr2 = arr2[arr2Index];
        if (valueArr1 < valueArr2) {
            merge2SortedArray[lastIndexMergeArray] = valueArr1;
            arr1Index++;
        } else if (valueArr1 > valueArr2) {
            merge2SortedArray[lastIndexMergeArray] = valueArr2;
            arr2Index++;
        } else {
            merge2SortedArray[lastIndexMergeArray] = valueArr1;
            lastIndexMergeArray++;
            merge2SortedArray[lastIndexMergeArray] = valueArr2;
            arr1Index++;
            arr2Index++;
        }
    }

    addLeftValues(arr1, arr1Index, merge2SortedArray, lastIndexMergeArray);
    addLeftValues(arr2, arr2Index, merge2SortedArray, lastIndexMergeArray);
    return merge2SortedArray;
}

private static void addLeftValues(int[] arr, int arrIndex, int[] merge2SortedArray, int lastIndexMergeArray) {
    for (int i = arrIndex; i < arr.length; i++) {
        merge2SortedArray[lastIndexMergeArray] = arr[i];
    }
}
黒涩兲箜 2025-02-13 06:51:09

当我们在流管线上应用sorted()操作时,在引擎盖下,它将分配内存中的数组,该数组将填充流中的元素并排序。

分类参考类型的数组Java使用,擅长在输入中发现排序的数据( arrays.aslist()因此,我认为我们正在谈论对象)。

因此,如果我们简单地将两个数据集串联起来,它仍然可以很好地表现。

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));

output:

[1, 2, 3, 4, 5]

如果要使用有条件的逻辑获取结果排序的数组,则必须使用循环的普通。这不是流的工作。

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

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));

输出:

[1, 2, 3, 4, 5]

When we apply sorted() operation on a stream pipeline, under the hood it'll allocate an array in memory that will be filled with elements of the stream and sorted.

To sort an array of reference type Java uses an implementation of the Timsort algorithm, which is good at spotting sorted chunks of data in the input (Arrays.asList() that you've used in your example expects varargs T, so I assume we are talking about objects).

Therefore, if we simply concatenate the two data sets it will still perform reasonably well.

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));

Output:

[1, 2, 3, 4, 5]

In case if you want to use conditional logic to obtain a sorted resulting array, then you must go with a plain for loop. It's not a job for a stream.

Using imperative programming, it can be implemented like that:

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));

Output:

[1, 2, 3, 4, 5]
相守太难 2025-02-13 06:51:09

流很好,但我建议您这样的方式,因为使用溪流,您首先必须将阵列更改为流式的阵列,以便在它们上工作,这可能会变得昂贵

public static String[] mergeAndSort(String[] arr1, String[] arr2) {
    int nums1Size = arr1.length;
    int nums2Size = arr2.length;

    String[] result = new String[nums1Size + nums2Size];  
    System.arraycopy(arr1, 0, result, 0, nums1Size);
    System.arraycopy(arr2, 0, result, nums1Size, nums2Size);

    Arrays.sort(result);
    return result;
}

Streams are nice but i recommend you this way because with streams you first have to change the arrays to streams only to work on them which could get expensive

public static String[] mergeAndSort(String[] arr1, String[] arr2) {
    int nums1Size = arr1.length;
    int nums2Size = arr2.length;

    String[] result = new String[nums1Size + nums2Size];  
    System.arraycopy(arr1, 0, result, 0, nums1Size);
    System.arraycopy(arr2, 0, result, nums1Size, nums2Size);

    Arrays.sort(result);
    return result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文