Java.util.Arrays.parallelPrefix in Java 8

Prerequisites:

The parallelPrefix method is introduced to the Arrays class in java 8. The parallelPrefix method performs a given mathematical function on the elements of the array cumulatively, and them modifies the array concurrently.
Syntax :

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

Variations :



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)

Lets understand parallelPrefix(int[] array, IntBinaryOperator op) with an example
Example 1: It illustrates some of the way in which you can pass the second argument(i.e.IntBinaryOperator)

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 extrenal 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 + "   "));
    }
}

chevron_right


Output:

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

As you can see in the example above parallelPrefix takes two parameter to IntBinaryOperator . It performs the given computation and update the second element keeping the first element as it is.

Example 2: This illustrates more operations on an array through parallelPrefix(int[] array, IntBinaryOperator op) and introduces parallelPrefix(int[] array, int fromIndex, int toIndex, IntBinaryOperator op).

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 + "   "));
    }
  
}

chevron_right


Output:

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   

Example 3 : This illustrates parallelPrefix(T[] array, BinaryOperator op) and
parallelPrefix(T[] array, int fromIndex, int toIndex, BinaryOperator op)

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Output:


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

Note : parallelPrefix() is explained with very basic operations you can try performing different operation on arrays by writing different lambda expressions.

Why should we use parallelPrefix() when we can do it sequentially ?

  • Parallel operations are much faster on larger size arrays but it usually depends on the Machine.
  • We use lambda while performing a parallel operation which reduces the number of lines in the code, making it more elegant and readable

References :
https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html
This article is contributed by Sumit Ghosh. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up

Improved By : Akanksha_Rai



Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.