我有这个二维数组:
System.IO.FileNotFoundException: Could not find file 'D:\home\site\wwwroot\bin\Monetary.Scheduling.xml'
首先,我想比较第一个元素和第二个元素,然后第二个元素与第三个元素进行比较,依此类推,逐行。
然后我想逐列地做同样的事情,比较元素[0,0]和元素[1,0],然后比较[1,0]和[2,0]等等对于每一列。
使用for()循环很容易做到:
int[][] matrix = new int[][] {
{ 4, 4, 4, 4, 4},
{ 4, 3, 4, 3, 4},
{ 4, 3, 4, 3, 4},
{ 4, 3, 4, 3, 3},
{ 1, 1, 1, 3, 3},
{ 4, 4, 4, 3, 3},
{ 4, 5, 4, 3, 3},
{ 4, 4, 4, 3, 3}};
但我需要的是使用带有lambda和流迭代的Java 8函数编程来做同样的事情。
答案 0 :(得分:2)
您提出的普遍适用的代码有点不清楚。但可能足以让你走上正确的道路。
假设您只是想找到相邻的副本:
//reference code
for (int[] row : matrix) {
for (int c = 0; c < row.length - 1; c++) {
if (row[c] == row[c + 1]) {
System.out.print(row[c]+" ");
}
}
}
//prints 4 4 4 4 3 1 1 3 4 4 3 3 4 4 3
我们还假设您的矩阵永远不会包含-1
。然后你可以做
//simple accumulator with a side effect of print out
IntBinaryOperator accumulator = (acc, x) -> {
if (acc == x) System.out.print(x + " ");
return x;
};
//also prints 4 4 4 4 3 1 1 3 4 4 3 3 4 4 3
Arrays.stream(matrix).forEach(arr -> Arrays.stream(arr).reduce(-1, accumulator));
reduce(-1, accumulator)
可以在任何int数组上工作,以找到彼此相邻的相同数字。累加器功能将先前的数字保存在acc中并与传入的数字进行比较。当然,身份-1
是作弊的,规范的方式是使用Arrays.stream(arr).boxed()...
并使用null
作为身份(它仍然会作弊,但会允许你矩阵中的所有整数)
这是另一个版本:
//prints 4 4 4 4 4 4 4 3 1 1 3 4 4 3 3 4 4 3
Arrays.stream(matrix).flatMapToInt(Arrays::stream).reduce(-1, accumulator);
这次没有forEach(),但由于它会使矩阵变平,它会将行的最后一个元素与下一行的第一个元素进行比较 - 可能是一个bug或一个特征。
最后,具有打印功能副作用的累加器在功能编程方面表现不佳。理想情况下,您应该collect()
重复列表并将其返回 - 因为您的问题非常模糊,我相信您可以使用上述信息自行编写。
你可以使用矩阵,流和重复的其他一些有趣的东西,例如:这将比两个嵌入式循环需要更多的编码:
Map<Integer,Long> m = Arrays.stream(matrix)
.parallel()
.flatMapToInt(Arrays::stream)
.boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(m); //prints occurences of each int: {1=3, 3=15, 4=21, 5=1}
最后,溪流不是银弹,不时只是一个很好的帮助。有些语言有更好的语法和更强大的结构来适应功能风格,但Java更喜欢别的东西。