【问题标题】:Java 8 Stream and operation on arraysJava 8 Stream 和数组操作
【发布时间】:2014-08-14 22:36:09
【问题描述】:

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

谢谢

【问题讨论】:

    标签: java arrays java-8 java-stream


    【解决方案1】:

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

    【讨论】:

    • int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray();
    • @Holger 是的,这也可以。虽然您可能想使用mapToInt 来避免装箱。
    • 最后一个相当于 zip 的模拟,您必须为结果预先分配存储空间。我想知道为什么 Streams 库中没有 zip?
    • 根据this SO answer 的说法,一个 zip 在 Java 8 的早期测试版中,然后被取出。幸运的是,海报有来源,它在答案中。我已经多次使用该代码,它似乎工作得很好。
    • @dkatzel — 因为它已经是一个 IntStream,“map”需要一个 IntUnaryOperator,所以不涉及装箱。
    【解决方案2】:

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

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

    获得流后,您可以使用the documentation 中描述的任何方法,例如sum() 或其他任何方法。您可以像在 Python 中一样使用 Lambda 函数调用相关的流方法来 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();
    

    【讨论】:

      【解决方案3】:

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

      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
      

      【讨论】:

        【解决方案4】:

        请注意,Arrays.stream(arr) 创建的是 LongStream(或 IntStream,...)而不是 Stream,因此 map 函数不能用于修改类型。这就是提供 .mapToLong、mapToObject、... 函数的原因。

        看看why-cant-i-map-integers-to-strings-when-streaming-from-an-array

        【讨论】:

          猜你喜欢
          • 2017-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-19
          • 2016-02-29
          • 1970-01-01
          相关资源
          最近更新 更多