📜  Java 8 中的Java .util.Arrays.parallelPrefix

📅  最后修改于: 2022-05-13 01:55:18.648000             🧑  作者: Mango

Java 8 中的Java .util.Arrays.parallelPrefix

先决条件:

  • Java 8 中的 Lambda 表达式
  • Java中的流

Java 8 中的Arrays 类中引入了parallelPrefix 方法。parallelPrefix 方法对数组的元素累积执行给定的数学函数,并同时修改数组。
句法 :

parallelPrefix(int[] array, IntBinaryOperator op)
Parameters :
array : integer array on which operation is to be performed
op : It is of type IntBinaryOperation (It represents an operation upon two int operands
and returns a result of type int)
Exception :
NullPointerException- Throws if the array or function passed as a parameter is null

变化 :

parallelPrefix(double[] array, DoubleBinaryOperator op)
parallelPrefix(double[] array, int fromIndex, int toIndex, DoubleBinaryOperator op)
parallelPrefix(int[] array, IntBinaryOperator op)
parallelPrefix(int[] array, int fromIndex, int toIndex, IntBinaryOperator op)
parallelPrefix(long[] array, int fromIndex, int toIndex, LongBinaryOperator op)
parallelPrefix(long[] array, LongBinaryOperator op)
parallelPrefix(T[] array, BinaryOperator op)
parallelPrefix(T[] array, int fromIndex, int toIndex, BinaryOperator op)

让我们通过一个例子来理解parallelPrefix(int[] array, IntBinaryOperator op)
示例 1:它说明了传递第二个参数的一些方法(即 IntBinaryOperator)

Java
// Java Program to illustrate parallelPrefix()
// and demonstrate different ways of
// passing parameter to it
import java.util.Arrays;
import java.util.function.IntBinaryOperator;
public class GFG {
     
    // Performs addition
    static int compute(int x, int y)
    {
        return x + y;
    }
 
    public static void main(String[] args) {
        int[] arr = { 2, 1, 7, 8, 4, 5, 6, 9, 8, 7, 1, 2, 3, 6, 5, 4, 7, 5 };
 
        // Uncomment to see different methods working
         
        /* Method 1(Creating an instance for IntBinaryOperator)
        //IntBinaryOperator op = (x, y) -> x + y;
        //Arrays.parallelPrefix(arr, op);
 
        // Method 2(Directly passing a lambda expression that evaluates to
        // return IntBinaryOperator)
        //Arrays.parallelPrefix(arr, (x, y) -> x + y);
 
        // Method 3(Declaring the operation in some external Function)
        Arrays.parallelPrefix(arr, GFG::compute); */
        Arrays.parallelPrefix(arr, (x,y) -> compute(x,y));
         
        // Printing the array elements
        Arrays.stream(arr).forEach(e -> System.out.print(e + "   "));
    }
}


Java
// Java program to demonstrate parallelPrefix
// on a range of a given array
 
import java.util.Arrays;
import java.util.function.IntBinaryOperator;
public class GFG {
 
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 
        // Example 1
        // With Primitive types
        // Performs addition with the adjacent element if first is less than
        // second else perform subtraction
 
        Arrays.parallelPrefix(arr, (x, y) -> {
            if (x < y)
                return x + y;
            else
                return x - y;
        });
        System.out.println("Example 1: with Primitive type");
 
        // Printing elements of array
        Arrays.stream(arr).forEach(e -> System.out.print(e + "   "));
 
        int[] arr1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 
        // Example 2
        // With primitives
        // Keeps on multiplying adjacent elements
 
        Arrays.parallelPrefix(arr1, (x, y) -> x * y);
        System.out.println("\nExample 2: with primitives");
 
        // Printing elements of array
        Arrays.stream(arr1).forEach(e -> System.out.print(e + "   "));
 
        // Lets examine parallelPrefix(int[] array, int fromIndex, int toIndex,
        // IntBinaryOperator op)
        // It is used when we want to make changes in the specified range of
        // elements in an array
 
        // Example:
        // If adjacent elements are even then it replace both the element with
        // first
        int[] arr2 = { 1, 2, 4, 8, 5, 9, 6, 8, 9, 10, 11 };
 
        Arrays.parallelPrefix(arr2, 2, 8, (x, y) -> {
            if (x % 2 == 0 && y % 2 == 0)
                return x;
            else
                return y;
        });
        System.out.println("\nExample: Making Changes in the "
                            +"specified range of element in an Array");
 
        // Printing element of array
        Arrays.stream(arr2).forEach(e -> System.out.print(e + "   "));
    }
 
}


Java
// Java program to demonstrate parallelPrefix
// on a user defined array
import java.util.Arrays;
import java.util.function.IntBinaryOperator;
public class GFG {
     
    // User defined class   
    static class Person{
        String name;
        int age;
         
        //constructor
        Person(String name, int age){
            this.name = name;
            this.age = age;
        }
    }
    public static void main(String[] args) {
         
        // Working with user defined class
        Person[] p = { new Person("Geek1", 10),
                       new Person("Geek2", 20), new Person("Geek3", 30),
                       new Person("Geek4", 40), new Person("Geek5", 50),
                       new Person("Geek6", 60), };
 
        // Example 1; Here we convert the first parameter to upper case and then
        // concatenate or add(in case of age) with the second through out the
        // array
        Arrays.parallelPrefix(p, (e1, e2) ->
                            new Person(e1.name.toUpperCase().concat(e2.name),
                                                e1.age + e2.age));
        System.out.println("\nExample 1 :");
 
        // Printing elements of the array
        Arrays.stream(p).forEach(e -> System.out.println(e.name + "   " + e.age));
         
 
        Person[] p1 = { new Person("Geek1", 10),
                        new Person("Geek2", 20), new Person("Geek3", 30),
                        new Person("Geek4", 40), new Person("Geek5", 50),
                    new Person("Geek6", 60), };
 
        // This illustrates the same modification as described above but within
        // a specified range
        Arrays.parallelPrefix(p1, 1, 4, (e1, e2) ->
                            new Person(e1.name.toUpperCase().concat(e2.name),
                                                e1.age + e2.age));
        System.out.println("\nExample 2 :");
         
        // Printing elements of array
        Arrays.stream(p1).forEach(e -> System.out.println(e.name + "   " + e.age));
    }
 
}


输出:

2   3   10   18   22   27   33   42   50   57   58   60   63   69   74   78   85   90   

正如您在上面的示例中看到的那样,parallelPrefix 将两个参数传递给 IntBinaryOperator。它执行给定的计算并更新第二个元素,保持第一个元素不变。
示例 2:这通过parallelPrefix(int[] array, IntBinaryOperator op)说明了对数组的更多操作,并引入了parallelPrefix(int[] array, int fromIndex, int toIndex, IntBinaryOperator op)

Java

// Java program to demonstrate parallelPrefix
// on a range of a given array
 
import java.util.Arrays;
import java.util.function.IntBinaryOperator;
public class GFG {
 
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 
        // Example 1
        // With Primitive types
        // Performs addition with the adjacent element if first is less than
        // second else perform subtraction
 
        Arrays.parallelPrefix(arr, (x, y) -> {
            if (x < y)
                return x + y;
            else
                return x - y;
        });
        System.out.println("Example 1: with Primitive type");
 
        // Printing elements of array
        Arrays.stream(arr).forEach(e -> System.out.print(e + "   "));
 
        int[] arr1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 
        // Example 2
        // With primitives
        // Keeps on multiplying adjacent elements
 
        Arrays.parallelPrefix(arr1, (x, y) -> x * y);
        System.out.println("\nExample 2: with primitives");
 
        // Printing elements of array
        Arrays.stream(arr1).forEach(e -> System.out.print(e + "   "));
 
        // Lets examine parallelPrefix(int[] array, int fromIndex, int toIndex,
        // IntBinaryOperator op)
        // It is used when we want to make changes in the specified range of
        // elements in an array
 
        // Example:
        // If adjacent elements are even then it replace both the element with
        // first
        int[] arr2 = { 1, 2, 4, 8, 5, 9, 6, 8, 9, 10, 11 };
 
        Arrays.parallelPrefix(arr2, 2, 8, (x, y) -> {
            if (x % 2 == 0 && y % 2 == 0)
                return x;
            else
                return y;
        });
        System.out.println("\nExample: Making Changes in the "
                            +"specified range of element in an Array");
 
        // Printing element of array
        Arrays.stream(arr2).forEach(e -> System.out.print(e + "   "));
    }
 
}

输出:

Example 1: with Primitive type
1   3   0   4   9   3   10   2   11   1   
Example 2: with primitives
1   2   6   24   120   720   5040   40320   362880   3628800   
Example: Making Changes in the specified range of element in an Array
1   2   4   4   5   9   6   6   9   10   11   

示例 3:这说明了parallelPrefix(T[] array, BinaryOperator op)
parallelPrefix(T[] 数组,int fromIndex,int toIndex,BinaryOperator op)

Java

// Java program to demonstrate parallelPrefix
// on a user defined array
import java.util.Arrays;
import java.util.function.IntBinaryOperator;
public class GFG {
     
    // User defined class   
    static class Person{
        String name;
        int age;
         
        //constructor
        Person(String name, int age){
            this.name = name;
            this.age = age;
        }
    }
    public static void main(String[] args) {
         
        // Working with user defined class
        Person[] p = { new Person("Geek1", 10),
                       new Person("Geek2", 20), new Person("Geek3", 30),
                       new Person("Geek4", 40), new Person("Geek5", 50),
                       new Person("Geek6", 60), };
 
        // Example 1; Here we convert the first parameter to upper case and then
        // concatenate or add(in case of age) with the second through out the
        // array
        Arrays.parallelPrefix(p, (e1, e2) ->
                            new Person(e1.name.toUpperCase().concat(e2.name),
                                                e1.age + e2.age));
        System.out.println("\nExample 1 :");
 
        // Printing elements of the array
        Arrays.stream(p).forEach(e -> System.out.println(e.name + "   " + e.age));
         
 
        Person[] p1 = { new Person("Geek1", 10),
                        new Person("Geek2", 20), new Person("Geek3", 30),
                        new Person("Geek4", 40), new Person("Geek5", 50),
                    new Person("Geek6", 60), };
 
        // This illustrates the same modification as described above but within
        // a specified range
        Arrays.parallelPrefix(p1, 1, 4, (e1, e2) ->
                            new Person(e1.name.toUpperCase().concat(e2.name),
                                                e1.age + e2.age));
        System.out.println("\nExample 2 :");
         
        // Printing elements of array
        Arrays.stream(p1).forEach(e -> System.out.println(e.name + "   " + e.age));
    }
 
}

输出:

Example 1 :
Geek1   10
GEEK1Geek2   30
GEEK1GEEK2Geek3   60
GEEK1GEEK2GEEK3Geek4   100
GEEK1GEEK2GEEK3GEEK4Geek5   150
GEEK1GEEK2GEEK3GEEK4GEEK5Geek6   210

Example 2 :
Geek1   10
Geek2   20
GEEK2Geek3   50
GEEK2GEEK3Geek4   90
Geek5   50
Geek6   60

注意: parallelPrefix() 使用非常基本的操作进行解释,您可以尝试通过编写不同的 lambda 表达式对数组执行不同的操作。

当我们可以按顺序执行时,为什么要使用 parallelPrefix() ?

  • 在较大尺寸的数组上并行操作要快得多,但它通常取决于机器。
  • 我们在执行并行操作时使用 lambda,这减少了代码中的行数,使其更加优雅和可读