我想知道Java 8是否可以实现以下功能:
Patch[][] patches = new Patch[width][depth];
我想使用Stream
来调用构造函数,我知道有Arrays.stream(patches)
可以给我一个Stream<Patch[]>
,所以不幸的是我认为没有任何用处(但是在我的想法中。)
在旧的Java中,这可以归结为简单:
for (int w = 0; w < width; w++) {
for (int z = 0; z < depth; z++) {
patches[w][z] = new Patch();
}
}
最有用的方法是将T[][]
破坏为Stream<T>
我认为的方法。
重新说明我真正想要的内容:将双for
- 循环转换为使用Java 8的语句,最有可能涉及Stream
。
答案 0 :(得分:1)
不幸的是我正在工作并且无法安装它来实际测试它,但是如果你真的想用Java 8用新的Patch
实例填充你的2d数组,你可以这样做:< / p>
import java.util.function.IntFunction;
public class PatchArrayGenerator implements IntFunction<Patch[]>
{
private final int depth;
public PatchArrayGenerator(int depth)
{
this.depth = depth;
}
public Patch[] apply(int value)
{
Patch[] patchArray = new Patch[depth];
Arrays.parallelSetAll(patchArray, value -> new Patch());
return patchArray;
}
}
public class PatchMaker
{
public static void main(String... args)
{
int depth = 5, width = 5;
Patch[][] patches = new Patch[width][depth];
Arrays.parallelSetAll(patches, new PatchArrayGenerator(depth));
}
}
如果您感到无聊,可以重构PatchArrayGenerator
类来创建您想要的任何类型,而不仅仅是补丁。
我肯定会坚持使用嵌套循环:)
答案 1 :(得分:1)
在了解了lambda的工作原理之后,我设法让它工作了:
Arrays.stream(patches)
.forEach(pArray -> Arrays.parallelSetAll(pArray, i -> new Patch()));
首先,我将解释一个更简单的版本:
Object[] test = new Object[10];
Arrays.parallelSetAll(test, i -> new Object());
上一版本的作用是首先分配一个Object[10]
,一个十Object
的数组。然后它使用具有以下签名的新Arrays.parallelSetAll
方法之一:
public static <T> void parallelSetAll(T[] array,
IntFunction<? extends T> generator)
在这种情况下,我使用IntFunction<? extends T> generator
lambda表达式i -> new Patch()
,为new Patch()
生成i
:在这种情况下,我们不需要虽然i
,但我们做需要它来构造一个正确的lambda表达式。
另请注意,Object::new
无法使用(据我所知),然后会给出消息:
incompatible types: cannot infer type-variable(s) T
(argument mismatch; bad return type in lambda expression
Object is not a functional interface)
where T is a type-variable:
T extends Object declared in method <T>parallelSetAll(T[],IntFunction<? extends T>)
回到我的问题的实际答案:我在那里做的非常类似于我刚才解释的,除了我有Patch[][]
作为输入,我首先需要循环,我通过以下方式完成:
Arrays.stream(patches).forEach()
,其签名为:void forEach(Consumer<? super T> action)
。
然后我在这里使用lambda表达式pArray -> Arrays.parallelSetAll(pArray, i -> new Patch())
。
这样有效地首先遍历所有Patch[]
数组,然后并行将Patch[]
的所有元素设置为new Patch()
。
它是否实际上比双循环更容易是有争议的,但我可以争辩说代码的数量至少相同,并且可能更容易键入,因为不需要输入,额外的花括号等。
这也许可以写得更容易,所以欢迎提出意见。