Java 8流和数组操作

216

我刚刚发现了新的Java 8流式编程功能。作为一名Python程序员,我想知道是否有一种简洁的方式可以像“一行Python代码”那样对数组进行加法、乘法等操作?

谢谢

4个回答

319

java.util.Arrays中添加了新的方法,可以将数组转换为Java 8流,然后可以用于求和等操作。

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

将两个数组相乘略微有些困难,因为我无法想到一种同时获取值和索引的流操作方法。这意味着你可能需要遍历数组的索引。

//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();

17
int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray(); - Holger
2
@Holger 是的,那也可以。不过你可能想使用 mapToInt 来避免装箱。 - dkatzel
最后一点相当于模拟zip,您必须为结果预分配存储空间。我想知道为什么Streams库中没有zip? - Reb.Cabin
根据这个SO答案,在Java 8的较早beta版本中,曾经有一个 zip 工具,但后来被移除了。幸运的是,该帖子的发布者拥有源代码,并在答案中提供了。我已经多次使用过这段代码,看起来非常有效。 - sparc_spread
2
@dkatzel — 由于它已经是IntStream,因此“map”采用IntUnaryOperator,因此不涉及装箱。 - M. Justin

62

使用 Arrays.stream() 可将数组转换为流:

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

得到流后,您可以使用文档中描述的任何方法,例如 文档 中所述的 sum() 或其他方法。通过使用 Lambda 函数调用相关的流方法,您可以像在 Python 中一样执行 mapfilter 操作:

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();

10

如果你需要处理大量数字,请小心。

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

5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接