Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing 2D array with streams in Java

I have the following class:

public class MyClass {
    //...
    public MyClass(int x, int y) {
        //...
    }
}

Now, I need to initialize 2D array with the items:

int rows;
int cols;
//initializing rows and cols
MyClass[][] arr = new MyClass[rows][cols];
//how to initialize arr[x][y] with 
//new MyClass(x, y) with streams API

I looked at this example, but it doesn't work in my case: Java 8 Stream and operation on arrays. They use a single IntStream.

Question: Of course I can use nested for loops, but I think it's now old-style and is considering bad. So how to apply streams api and initilize it in Java 8 way?


2 Answers

Streams are not very good at keeping track of index, which you need here. So you can abuse them like @NicolasFilotto proposes, or in a simpler way:

MyClass[][] array = new MyClass[rows][cols];
IntStream.range(0, rows)
        .forEach(r -> IntStream.range(0, cols)
                .forEach(c -> array[r][c] = new MyClass(r, c)));

You could even make it look more functional and get rid of the forEach and the mutation part:

MyClass[][] array = IntStream.range(0, rows)
        .mapToObj(r -> IntStream.range(0, cols)
                .mapToObj(c -> new MyClass(r, c))
                .toArray(MyClass[]::new))
        .toArray(MyClass[][]::new);

But honestly, for loops are not obsolete:

for (int r = 0; r < rows; r++) {
    for (int c = 0; c < cols; c++) {
        array[r][c] = new MyClass(r, c);
    }
}
like image 81
assylias Avatar answered Jun 08 '26 13:06

assylias


Here is a way to do it:

int rows = 5;
int cols = 10;
MyClass[][] arr = new MyClass[rows][cols];
Stream.generate(new Supplier<MyClass>() {
    int currentValue = 0;
    @Override
    public MyClass get() {
        MyClass myClass = new MyClass(currentValue / cols, currentValue % cols);
        currentValue++;
        return arr[myClass.x][myClass.y] = myClass;
    }
}).limit(rows * cols).forEach(System.out::println);

Output:

MyClass{x=0, y=0}
MyClass{x=0, y=1}
MyClass{x=0, y=2}
...
MyClass{x=4, y=9}
like image 20
Nicolas Filotto Avatar answered Jun 08 '26 13:06

Nicolas Filotto



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!