在Java 8版本之前,我们可以使用如下所示的for循环初始化二维数组。如何在JDK 1.8中使用Lambda表达式执行以下操作?
int[][] board = new int[3][3];
int v = 1;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = v;
v++;
System.out.println(v);
}
}
System.out.println(Arrays.deepToString(board));
基本上,我正在寻找类似下面的数组
[[1,6],[2,7],[3,8],[4,9]]
答案 0 :(得分:1)
使用IntStream
。这将创建一个连续的整数流,从0
到n
不包括整数。因此,对于3 x 3矩阵,IntStream
是0, 1, 2
。
为外部流中从IntStream
到列数(也为3)的每个整数再创建一个0
。
您不能在流中递增v
,因为它必须是“有效的最终”。取而代之的是,我们使用公式board[j][i] = 1 + (j + m * i)
,它与将板展平为单个数组(一维矩阵)时实际上类似于计算值的索引。
import java.util.stream.IntStream;
import java.util.Arrays;
class J {
public static void main(String[] args) {
int n = 4;
int m = 2;
// n x m matrix
int[][] board = new int[n][m];
// Cols (m)
IntStream.range(0, m).forEach( i -> {
// Rows (n)
IntStream.range(0, n).forEach( j -> {
// Multiply i by row count
// to account for the row we are in
board[j][i] = 1 + (j + n * i);
});
});
System.out.println(Arrays.deepToString(board));
}
}
输出:
[[1, 5], [2, 6], [3, 7], [4, 8]]
注意:仅仅因为流允许您编写更整洁的,类似于函数式编程的语法,所以常常会产生性能损失。它强调了一个想法:“为什么要修复未损坏的东西?”。对于3 x 3的面板,您可能看不到任何区别。但是,如果您的木板更大,考虑到所有创建的对象以及幕后使用的额外空间,它可能不会证明自己值得。有时,简单的for循环(尤其是在使用数组时)会更好。
记住,简单是关键。
答案 1 :(得分:0)
我强烈建议您坚持使用for-loop
来初始化具有原始值的数组。对于多维数组,我的建议更强。
但是,方法如下:
int a = 4; // Number of outer array elements
int b = 2; // Number of inner array elements
int[][] board = IntStream
.range(0, a) // iterate 0..3
.mapToObj(i -> IntStream.range(0, b) // for each iteratoe 0..1
.map(j -> 1 + (i + (a + 1) * j)) // calculate the value
.toArray()) // compose the inner array
.toArray(int[][]::new); // compose the outer array
请注意,IntStream
可以创建一个基本数组,因为它是一个基本整数值元素的序列。其方法IntStream::toArray
要求int[]
。
外部数组的组成有些棘手,因为int[]
不再是原始值,而是数组本身。需要使用将int
映射到对象的方法IntStream::mapToObj
-然后返回Stream<int[]>
,并且必须使用将方法Stream::toArray(IntFunction<A[]> generator)
转换为带有参数的数组,因为您不能将Object[]
转换为int[][]
。
传递的参数很简单。 int[][]::new
与i -> new int[a][b]
没什么不同。
答案 2 :(得分:0)
您可以结合使用IntStream
方法range
和iterate
:
int width = 4, height = 2;
IntStream.rangeClosed(1, width)
.mapToObj(column -> IntStream.iterate(column, v -> v + width)
.limit(height)
.toArray())
.toArray(int[][]::new);
通过将iterate
用于内部循环,并使用rangeClosed(1, width)
而不是range(0, width)
,我们可以稍微简化计算过程。使用toArray
消除了您自己创建和修改数组的需要,并且将启用并行处理。
重要的是,实际上实际使用流可以使它们不仅仅是寻找怪异的循环。仅用range(0, x).forEach(...)
替换循环以修改局部变量并不能真正“使用流”,因此最好坚持使用for循环。
答案 3 :(得分:0)
这里是“嵌套循环”的流解决方案。
int [] []板的输出= new int [4] [2];
[[1,6],[2,7],[3,8],[4,9]]
int [] []板的输出= new int [4] [3];
[[1,6,11],[2,7,12],[3,8,13],[4,9,14]]
int step = 5;
IntStream.range(0, board.length).forEach(i ->
IntStream.range(0, board[i].length).forEach(j ->
board[i][j] = i + j * step + 1
)
);