Java 8 中对多维数组的方法引用
Method references to multidimensional arrays in Java 8
在 Java 中,我们可以从一维数组构造函数参考创建 IntFunction<String[]>
:
// both do the same thing
IntFunction<String[]> createArrayL = size -> new String[size];
IntFunction<String[]> createArrayMR = String[]::new;
现在我想知道为什么我们不能用二维数组来做这个:
BiFunction<Integer, Integer, String[][]> createArray2DL =
(rows, cols) -> new String[rows][cols];
// error:
BiFunction<Integer, Integer, String[][]> createArray2DMR =
String[][]::new;
当然可以这样写:
IntFunction<String[][]> createArray2DInvalidL = String[][]::new;
System.out.println(createArray2DInvalidL.apply(3)[0]); // prints null
但这与以下行为不同:
new String[3][3]
因为行数组不会被初始化
所以我的问题是:为什么 String[][]::new
不适用于二维数组(对我来说,这看起来像是语言设计的不一致)?
确实是一个很有趣的案例。
问题是 String[][]::new
是一个元数为 1 的函数(它是数组数组的构造函数)并且不能被视为 BiFunction(元数为 2)和你的例子 new String[3][3]
有两个参数而不是一个。
在这种情况下,
createArray2DInvalidL.apply(3)
等于调用new String[3][];
您可能正在寻找的是:
IntFunction<String[][]> createArray2D = n -> new String[n][n];
维度不需要具有相同的长度,这听起来像是一个非常合理的假设。
http://4comprehension.com/multidimensional-arrays-vs-method-references/
这里没有矛盾。如果你写这样的语句
IntFunction<ElementType[]> f = ElementType[]::new;
您创建了一个函数,其计算将 return 一个新数组,其中每个条目都能够保存 ElementType
的引用,并初始化为 null
。当您将 String[]
用于 ElementType
.
时,这不会改变
但它也已在 The Java Language Specification, §15.13.3. Run-Time Evaluation of Method References 中明确解决:
If the form is Type[]k :: new (k ≥ 1), then the body of the invocation method has the same effect as an array creation expression of the form new Type [ size ] []k-1, where size is the invocation method’s single parameter. (The notation []k indicates a sequence of k bracket pairs.)
不支持矩形多维数组创建方法参考,很可能是因为没有作为驱动力的实际用例。一维数组创建表达式可以与 Stream.toArray(…)
一起使用,允许比等效的 lambda 表达式更简洁的语法,尽管底层架构没有特殊支持,即 int[]::new
产生完全相同的编译代码为 intArg -> new int[intArg]
。对于二维(或更多)维数组创建没有类似的用例,因此对于使用两个或更多 int
值并产生引用类型结果的函数甚至没有类似的功能接口。
在 Java 中,我们可以从一维数组构造函数参考创建 IntFunction<String[]>
:
// both do the same thing
IntFunction<String[]> createArrayL = size -> new String[size];
IntFunction<String[]> createArrayMR = String[]::new;
现在我想知道为什么我们不能用二维数组来做这个:
BiFunction<Integer, Integer, String[][]> createArray2DL =
(rows, cols) -> new String[rows][cols];
// error:
BiFunction<Integer, Integer, String[][]> createArray2DMR =
String[][]::new;
当然可以这样写:
IntFunction<String[][]> createArray2DInvalidL = String[][]::new;
System.out.println(createArray2DInvalidL.apply(3)[0]); // prints null
但这与以下行为不同:
new String[3][3]
因为行数组不会被初始化
所以我的问题是:为什么 String[][]::new
不适用于二维数组(对我来说,这看起来像是语言设计的不一致)?
确实是一个很有趣的案例。
问题是 String[][]::new
是一个元数为 1 的函数(它是数组数组的构造函数)并且不能被视为 BiFunction(元数为 2)和你的例子 new String[3][3]
有两个参数而不是一个。
在这种情况下,
createArray2DInvalidL.apply(3)
等于调用new String[3][];
您可能正在寻找的是:
IntFunction<String[][]> createArray2D = n -> new String[n][n];
维度不需要具有相同的长度,这听起来像是一个非常合理的假设。
http://4comprehension.com/multidimensional-arrays-vs-method-references/
这里没有矛盾。如果你写这样的语句
IntFunction<ElementType[]> f = ElementType[]::new;
您创建了一个函数,其计算将 return 一个新数组,其中每个条目都能够保存 ElementType
的引用,并初始化为 null
。当您将 String[]
用于 ElementType
.
但它也已在 The Java Language Specification, §15.13.3. Run-Time Evaluation of Method References 中明确解决:
If the form is Type[]k :: new (k ≥ 1), then the body of the invocation method has the same effect as an array creation expression of the form new Type [ size ] []k-1, where size is the invocation method’s single parameter. (The notation []k indicates a sequence of k bracket pairs.)
不支持矩形多维数组创建方法参考,很可能是因为没有作为驱动力的实际用例。一维数组创建表达式可以与 Stream.toArray(…)
一起使用,允许比等效的 lambda 表达式更简洁的语法,尽管底层架构没有特殊支持,即 int[]::new
产生完全相同的编译代码为 intArg -> new int[intArg]
。对于二维(或更多)维数组创建没有类似的用例,因此对于使用两个或更多 int
值并产生引用类型结果的函数甚至没有类似的功能接口。