【发布时间】:2018-04-15 03:41:52
【问题描述】:
与办公室周围的人谈论这件事让我意识到,如果没有我如何到达这里的背景,他们的回答总是“你做错了”,所以这里是背景:
我必须处理另一个团队使用 ICE (https://doc.zeroc.com/display/Ice37/Ice+Overview) 创建的糟糕对象,并且想为我一直在编写的样板代码编写一个实用程序。
我必须处理的对象之一是浮点数和字符串的容器。我只想要浮点值。
public class FloatWrapper {
public String StringValue;
public float FloatValue;
public FloatWrapper(float f) {
this.FloatValue = f;
}
public FloatWrapper(String s) {
this.StringValue = s;
}
public FloatWrapper(float f, String s) {
this.FloatValue = f;
this.StringValue = s;
}
}
这个容器以二维数组的形式交付给我,所以我想要一个 float[][]。让我们从一维开始
FloatWrapper[] wrappers = new FloatWrapper[] {
new FloatWrapper(1.0f),
new FloatWrapper(2.0f)
};
Float[] asFloats = Arrays.stream(wrappers)
.map(f -> f.FloatValue)
.toArray(Float[]::new);
这很容易。让我们尝试一个二维数组。
// Make a lovely method for what I have above
public Float[] convert1Darray(FloatWrapper[] wrappers) {
return Arrays.stream(wrappers)
.map(f -> f.FloatValue)
.toArray(Float[]::new);
}
public static Float[][] convert2Darray(FloatWrapper[][] wrappers) {
return Arrays.stream(wrappers)
.map(f -> convert1Darray(f))
.toArray(Float[][]::new);
}
...
// Create a 2D array
FloatWrapper[][] wrappers2d = new FloatWrapper[][] {
{ new FloatWrapper(1.0f), new FloatWrapper(2.0f) },
{ new FloatWrapper(3.0f), new FloatWrapper(4.0f) }
};
Float[][] floats2d = convert2Darray(wrappers2d);
轰隆隆!
如果有原始的花车就好了(它只是,好吧!)你们中间的干瘪的人可以看到我要去哪里......
原来你不能在“toArray”调用中很容易地使用原始浮点数。 Apache commons 会对其进行排序
public static float[] convert1DprimitiveArray(FloatWrapper[] wrappers) {
return ArrayUtils.toPrimitive(
Arrays.stream(wrappers)
.map(f -> f.FloatValue)
.toArray(Float[]::new));
}
public static float[][] convert2DprimitiveArray(FloatWrapper[][] wrappers) {
return Arrays.stream(wrappers)
.map(f -> convert1DprimitiveArray(f))
.toArray(float[][]::new);
}
....等一下。为什么我可以使用 'toArray(float[][]::new)' 而不是 'toArray(float[]::new)' ?
现在在办公室里流传的论点是“float[]::new”调用是非法的,因为您不能在原语上调用“new”。
但这不是它正在做的事情。这只是 IntFunction 的简写
让我们分解一下
这个:
Arrays.stream(wrappers1d).map(f -> f.FloatValue).toArray(Float[]::new);
相当于这个:
Arrays.stream(wrappers1d).map(f -> f.FloatValue).toArray(new IntFunction<Float[]>() {
@Override
public Float[] apply(int size) {
return new Float[size];
}
});
那么,是不是你不能创建 IntFuntion 类型的东西??
不。完全允许:
IntFunction<float[]> happyToCompile = new IntFunction<float[]>() {
@Override
public float[] apply(int size) {
return new float[size];
}
};
执行该功能会给您带来等价的
new float[]{ 0.0f, 0.0f };
所以,我半知半解的猜测是,当你有一个二维数组而不是一维数组时,IntFunction 会进行一些类型推断。但是,“可以”吗?
【问题讨论】:
标签: java arrays generics lambda