1

This question is related to How do I copy a 2 Dimensional array in Java?

But how would you copy an array using streams in Java 8 / 9?

This is what I came up with:

static int[][] cloneArray(int[][] array) {
    return IntStream.range(0, array.length).collect(
            () -> new int[array.length][],
            (ints, i) -> ints[i] = array[i].clone(),
            (ints, i) -> {});
}

Is there a more elegant or performant way to copy a 2D array using streams?

6
  • 2
    Why do you box the ints? That's gonna kill the performance definitely. Commented Jan 3, 2018 at 9:19
  • 1
    Can't really see how this is an improvement on the various non-stream ways, unless your intention is to make your code slower and much harder to read. Commented Jan 3, 2018 at 9:22
  • @Kayaman: yes, that is silly. I have updated the question. Commented Jan 3, 2018 at 9:29
  • @khelwood; I have removed boxing. Why is performance so much slower? Commented Jan 3, 2018 at 9:36
  • I think the issue here is assuming that streams would somehow provide a better or faster way. A basic task like array copying is already solved efficiently, there are no huge advantages to be had. Commented Jan 3, 2018 at 9:48

2 Answers 2

4
return Arrays.stream(x).map(r->Arrays.copyOf(r, r.length)).toArray(int[][]::new);

I think this is an improvement because you're not allocating a nxm array then replacing all of the m length ones with a copy.

Sign up to request clarification or add additional context in comments.

4 Comments

I like it, because it is very compact. But what about performance?
You're not double allocating in this way. You could probably improve your attempt by replacing the .clone call with System.arraycopy or at the very least, ditch the array[0].length and leave that part empty.
Is .clone slower than System.arraycopy? Thank you for the suggestion to leave the array[0].length empty.
You'll have trouble measuring the difference, as per this question. stackoverflow.com/questions/12157300/clone-or-arrays-copyof Although in your case for a 2D array, where each row is the same length, I suspect they System.arraycopy will be the fastest because it allocates everything upfront.
2

You can do it straight-forwardly using

static int[][] cloneArray(int[][] x) {
    return Arrays.stream(x).map(int[]::clone).toArray(int[][]::new);
}

Note that this works for any ElementType with a public method ElementType clone(), like

static ElementType[] cloneArray(ElementType[] x) {
    return Arrays.stream(x).map(ElementType::clone).toArray(ElementType[]::new);
}

and in your case, ElementType happens to be int[].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.