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,这减少了代码中的行数,使其更加优雅和可读