Java 8流和对数组的操作


197

我刚刚发现了新的Java 8流功能。来自Python,我想知道现在是否有一种巧妙的方法可以对数组进行操作,例如求和,以“单行pythonic”的方式将两个数组相乘?

谢谢

Answers:


294

添加了新方法java.util.Arrays来将数组转换为Java 8流,然后将其用于求和等。

int sum =  Arrays.stream(myIntArray)
                 .sum();

将两个数组相乘会有点困难,因为我无法想到一种与Stream操作同时获取值和索引的方法。这意味着您可能必须流式处理数组的索引。

//in this example a[] and b[] are same length
int[] a = ...
int[] b = ...

int[] result = new int[a.length];

IntStream.range(0, a.length)
         .forEach(i -> result[i] = a[i] * b[i]);

编辑

批评家@Holger指出,你可以使用map方法,而不是forEach像这样:

int[] result = IntStream.range(0, a.length).map(i -> a[i] * b[i]).toArray();

13
int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray();
Holger 2014年

2
@Holger是的,也可以。虽然您可能要mapToInt避免使用拳击。
dkatzel

最后一个相当于zip的模拟,您必须在其中为结果预分配存储空间。我想知道为什么Streams库中没有zip?
Reb.Cabin

根据这个SO答案,一个zip在Java 8的早期beta版本中,然后被取出。幸运的是,海报有出处,就在答案中。我已经使用了几次该代码,它似乎工作得很好。
sparc_spread '16

@dkatzel —由于它已经是一个IntStream,因此“地图”使用一个IntUnaryOperator,因此不涉及拳击。
M. Justin

58

您可以使用以下命令将数组转换为流Arrays.stream()

int[] ns = new int[] {1,2,3,4,5};
Arrays.stream(ns);

获得流之后,可以使用文档中描述的任何方法,例如sum()或类似方法。您可以在Python中mapfilter通过在Lambda函数中调用相关的流方法来实现:

Arrays.stream(ns).map(n -> n * 2);
Arrays.stream(ns).filter(n -> n % 4 == 0);

修改完流之后,您可以调用toArray()将其转换回数组以在其他地方使用:

int[] ns = new int[] {1,2,3,4,5};
int[] ms = Arrays.stream(ns).map(n -> n * 2).filter(n -> n % 4 == 0).toArray();

9

如果必须处理大量数据,请小心。

int[] arr = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE};
long sum = Arrays.stream(arr).sum(); // Wrong: sum == 0

上面的总和不是2 * Integer.MIN_VALUE。在这种情况下,您需要这样做。

long sum = Arrays.stream(arr).mapToLong(Long::valueOf).sum(); // Correct

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.