Home > other >  Create two dimensional array using java streams [duplicate]
Create two dimensional array using java streams [duplicate]

Time:09-22

I want to merge two arrays into one array using streams.

List<String> x = new ArrayList<>();
List<String> y = new ArrayList<>();
final String xx[] = new String[] { "D", "E", "F", "G" };
final String yy[] = new String[] { "1", "2", "3", "4" };
/* Old implementation -> We want to replace it with streams
for(String xx : x) {
  for(String yy : y) {
    result.add(x y);
  }
}
*/
// String result[] = {"D1", "D2", "D3", ... "F3", "F4", "G1", .... , "G4"}

CodePudding user response:

Iterate over xx, and iterate over yy for each element. Use flatMap to produce a flat stream:

String[] result = Arrays.stream(xx)
    .flatMap(e -> Arrays.stream(yy).map(f -> e   f))
    .toArray(String[]::new);

This isn't really an improvement over the nested loops.

CodePudding user response:

That seems rather pointless; this is one of those jobs where writing it as a double for loop is a lot simpler and more understandable than doing it with streams. Streams are just a tool. They usually are worse (lambdas aren't transparent for exceptions, local variables, and control flow. This is bad when they are run in-line, and for streams, that's usually the case. You need to weigh that downside against the upside of allowing the collection data structure to manage iterations. Which is usually no upside whatsoever, and readability, which in this case, is worse, not better. Conclusion: Streams lose on all fronts here, so don't).

For academic exercise, here's how you would do that. flatMap lets you expand a single stream item into 0 to many stream items, which is how we're going to get it done.

final String[] xx = new String[] { "D", "E", "F", "G" };
final String[] yy = new String[] { "1", "2", "3", "4" };

var list1 = Arrays.stream(xx)
  .flatMap(x -> Arrays.stream(yy).map(y -> x   y))
  .collect(Collectors.toList());

var list2 = new ArrayList<String>();
for (var x : xx) for (var y : yy) list2.add(x   y);

Note how the second snippet is simpler and shorter.

CodePudding user response:

What you could use is something like this:

String[] result = Arrays.stream(xx) //create a stream for xx
                        .flatMap(x -> //flat map each element into another stream
                             Arrays.stream(yy) //we'll flat map into a stream of yy for every x
                                   .map(y -> x   y)) //the stream elements will be x y                            
                        .toArray(String[]::new); //collect into an array

As you can see, the code is not much more readable than a simple traditional loop like yours:

List<String> list = new LinkedList<>();
for(String xx : x) {
  for(String yy : y) {
    list.add(x y);
  }
}
String[] result = list.toArray(String[]::new);

One thing you might use more easily with streams would be parallelization but you'd need really large source arrays to actually get any advantage out of this.

  • Related