Initializing 2d array with streams in Java

风格不统一 提交于 2019-12-07 12:41:46

问题


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. 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 Java8 way?


回答1:


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



回答2:


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}



回答3:


Adaptation for Integer[][] for solution: answered assylias:

package com.gmail.jackkobec.java.core;

import java.util.Arrays;
import java.util.Random;
import java.util.stream.IntStream;

/**
 * @Author Jack <jackkobec>
 */
public class InitMatrixByStreamApi {
    public static final int ROWS_COUNT = 5; // Matrix rows number
    public static final int COLUMN_COUNT = 2; // Matrix columns number

    public static void main(String[] args) {

        Integer[][] matrixFromStreamApi = initMatrixInStream(ROWS_COUNT, COLUMN_COUNT);
        printMatrix(matrixFromStreamApi);
    }

    /**
     * Init matrix by random int values with border 777
     *
     * @param rowsCount    - Matrix rows number
     * @param columnsCount - Matrix columns number
     * @return Integer[][]
     */
    public static Integer[][] initMatrixInStream(int rowsCount, int columnsCount) {
        return IntStream.range(0, rowsCount)
                .mapToObj(rowArray -> IntStream.range(0, columnsCount)
                        .mapToObj(columnArrayElement -> new Random().nextInt(777)).toArray(Integer[]::new)
                )
                .toArray(Integer[][]::new);
    }

    /**
     * Prints matrix.
     *
     * @param matrix
     */
    public static void printMatrix(Integer[][] matrix) {
        Arrays.stream(matrix)
                .map(array -> Arrays.toString(array) + "\n")
                .forEach(System.out::println);
    }
}

[395, 58]

[361, 652]

[291, 76]

[112, 77]

[186, 282]



来源:https://stackoverflow.com/questions/37077322/initializing-2d-array-with-streams-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!