【问题标题】:Java 8 - best way converting array elementsJava 8 - 转换数组元素的最佳方式
【发布时间】:2015-08-14 07:54:54
【问题描述】:

从 Java 8 开始,所以需要一点时间来适应它。这是一个经典问题,我有一个要转换的对象数组。

在 Java8 之前,理想的代码应该是(没有空指针):

P[] outputArray = new P[inputArray.length];
for (int i =0; i< inputArray.length; i++ )
{
    outputArray [i] = inputArray[i].transformToP();
}

Java8 最好的版本是什么?

【问题讨论】:

标签: java java-8 java-stream


【解决方案1】:

使用 Stream API 非常简单:

P[] outputArray = Arrays.stream(inputArray).map(e -> e.transformToP()).toArray(P[]::new);

也可以使用方法引用(假设I是输入元素的类型):

P[] outputArray = Arrays.stream(inputArray).map(I::transformToP).toArray(P[]::new);

请注意,如果transformToP() 方法抛出检查异常,您可能会遇到问题。在这种情况下,将它们转换为未选中的或咨询this 问题。

【讨论】:

  • 如果您更喜欢Arrays.stream(inputArray),还有一个Stream.of(inputArray)
  • @Keppil,是的,我想这是风格的问题。
【解决方案2】:

在数组上使用流是一种很好的技术,如Tagir Valeev's answer 中所述。但是,不要忘记Arrays.setAll。这是一个方便的快捷方式,用于根据索引设置数组的所有元素。要通过某个函数将数组转换为新数组,您可以这样做:

P[] outputArray = new P[inputArray.length];
Arrays.setAll(outputArray, i -> inputArray[i].transform());

您不必将其复制到新数组中。如果你想就地转换数组,你可以这样做:

Arrays.setAll(array, i -> array[i].transform());

还有一个平行变化parallelSetAll

在幕后,这只是输入数组索引上的 IntStream.range,但有时对于快速单行来说非常方便。

【讨论】:

  • 不错的补充,点赞。虽然 OP 的 transformToP 建议 outputArray 类型 P 不同于 inputArray 类型。顺便说一句,像Arrays.replaceAll(array, fn) 这样传递给fn 的东西不是数组索引而是当前值是非常有用的,所以你可以写Arrays.replaceAll(array, P::transform);
  • @TagirValeev 谢谢。 Arrays 确实有很多“缺失”的东西会非常有用。问题是Arrays 已经太混乱了,任何添加都意味着添加子范围变化和原始特化。
  • 我明白了。我一直想知道是否可以将此类方法直接添加到数组类型中(使用类似array.setAll(i -&gt; array[i].transform());)。已经有一个clone() 方法可以直接在数组类型中使用。为什么不添加更多与数组相关的方法,而不是让Arrays 类变得混乱呢?原始特化将仅位于相应的原始数组类型中。好吧,它可能需要对语言进行重大更改,但它会使代码更加清晰。 javac 可能只是将此类调用转换为静态方法调用。
  • @TagirValeev 已知问题。 :-) 不幸的是,clone() 方法和数组的length 字段在语言中非常特殊。有一些想法可以使数组实现某些接口,因此这些东西将被显式声明,甚至可能被扩展。在2012 JVMLS 上查看 John Rose 的“Arrays 2.0”演讲。但是请注意,尽管其中一些已经原型化,但据我所知,没有一个是为 JDK 9 提交的。
  • 不错,暂时是我最喜欢的,因为它创建的对象更少(是的,是的,有时它很重要)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 2017-09-19
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
相关资源
最近更新 更多