Java 8中的数组流
在这篇文章中,我们将了解Java 8中增加的数组类的流方法,它简化了对数组的许多操作,并提高了效率。
在Java 8中增加了不同的功能,如lambdas和流,使Java能够有效地编写优雅的代码,在大多数情况下提高了可读性,提供了性能的效率。
语法:
public static IntStream stream(int[] arr)
Parameter :
arr - An array which is to be converted to the stream
Returns :
An IntStream of an array
变体:
public static IntStream stream(int[] array)
public static IntStream stream(int[] array, int startInclusive, int endExclusive)
public static DoubleStream stream(double[] array)
public static DoubleStream stream(double[] array, int startInclusive, int endExclusive)
public static LongStream stream(long[] array)
public static LongStream stream(long[] array, int startInclusive, int endExclusive)
public static Stream stream(T[] array)
public static Stream stream(T[] array, int startInclusive, int endExclusive)
注: - 即使你不熟悉这些主题,你也可以通过这篇文章,因为它使用了非常基本的Lambda表达式,并解释了如何使用流类的方法。
让我们看一个关于数组流的例子。在这个例子中,我们将寻找数组元素的平均数,并将看到用命令式和声明式写代码的方式的不同。
例1 :
import java.util.Arrays;
class GFG_Demo_1 {
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
// Let's try the imperative style first(which we
// are familiar with)
int sum = 0;
for (int i = 0; i < arr.length; i++)
sum += arr[i];
System.out.println("Average using iteration :" +
(sum / arr.length));
// Let's try the declarative style now
sum = Arrays.stream(arr) // Step 1
.sum(); // Step 2
System.out.println("Average using streams : " +
(sum / arr.length));
// forEach()
// It iterates through the entire streams
System.out.println("Printing array elements : ");
Arrays.stream(arr)
.forEach(e->System.out.print(e + " "));
}
}
输出
Average using iteration :10
Average using streams : 10
Printing array elements :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
在上面的例子中,你已经看到了流的作用,让我们看看这些步骤的作用。
第1步:
Arrays.stream(arr) – 在这一步中,我们调用Arrays类的stream方法,将arr作为参数传给函数,该语句返回IntStream。
第2步:
Arrays.stream(arr).sum() – 一旦我们得到IntStream,我们就可以使用IntStream接口的不同方法。
当你浏览IntStream .接口文档时,你可以打开每个方法,看它是执行终端操作还是中间操作。我们应该相应地使用这个方法,要么在终端操作,要么在中间操作。
现在让我们去看看IntStream的不同方法,看看这些方法执行什么操作。我们将看到所有这些方法的例子,与一个数组的对比。
在下面的例子中,我们将通过以下方法。
- asDoubleStream()
- asLongStream()
- anyMatch()
- allMatch()
- noneMatch()
import java.util.Arrays;
import java.util.function.IntPredicate;
class GFG_Demo_2 {
public static void main(String[] args)
{
int arr_sample1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
// asDoubleStream()
// It converts the original array to double
System.out.println("Example of asDoubleStream(): ");
Arrays.stream(arr_sample1)
.asDoubleStream()
.forEach(e->System.out.print(e + " "));
// asLongStream()
// It converts the original array to Long
System.out.println("\nExample of asLongStream");
Arrays.stream(arr_sample1)
.asLongStream()
.forEach(e->System.out.print(e + " "));
int arr_sample2[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
// anyMatch()
// This method find whether the given predicate
// is in the array or not
System.out.println("\nExample of anyMatch");
// Test whether any of the element in array is
// divisible by 11 or not
IntPredicate predicate = e->e % 11 == 0;
System.out.println(Arrays.stream(arr_sample2)
.anyMatch(predicate));
// You can directly write the lambda expression
// which computes to IntPredicate
// Uncomment to test
// System.out.println(Arrays.stream(arr)
// .anyMatch(e -> e % 11 == 0));
int arr_sample3[] = { 2, 4, 6, 8, 10 };
int arr_sample4[] = { 1, 3, 5, 7, 11 };
// allMatch()
// This method finds whether the given predicate
// matches the entire array or not
System.out.println("Example of allMatch :");
// Returns true as all the elements of arr_sample3
// is even
System.out.println(Arrays.stream(arr_sample3)
.allMatch(e->e % 2 == 0));
// Returns false as all the elements of arr_sammple4
// is odd
System.out.println(Arrays.stream(arr_sample4)
.allMatch(e->e % 2 == 0));
// noneMatch()
System.out.println("Example of noneMatch");
System.out.println(Arrays.stream(arr_sample4)
.noneMatch(e->e % 2 == 0));
}
}
输出
Example of asDoubleStream():
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0
14.0 15.0 16.0 17.0 18.0 19.0 20.0
Example of asLongStream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Example of anyMatch
false
Example of allMatch :
true
false
Example of noneMatch
true
虽然IntStream提供了更多的方法,但我们已经看到了很少的方法,让我们再试一下。
我们将在下面的例子中通过以下方法。
- 平均值()
- findAny()
- findFirst()
- max()
- min()
- reduce()
请记住所有这些方法返回OptionalInt或OptionalDouble,而不是int或double。
import java.util.Arrays;
class GFG_Demo_3 {
public static void main(String[] args)
{
int arr_sample1[] = { 11, 2, 3, 42, 5, 6, 17, 8, 9,
10, 11, 12, 13, 24, 55, 16, 47, 18, 19, 20 };
System.out.println("These method returns Optional");
// average()
// This method returns a average of an array
System.out.println("Example of average() : ");
System.out.println((Arrays.stream(arr_sample1)
.average()));
// findAny()
// It can return any value from the stream
// Most of the time it returns the first value
// but it is not assured it can return any value
System.out.println("Example of findAny() : ");
System.out.println(Arrays.stream(arr_sample1)
.findAny());
// findFirst()
// It returns the first element of the stream
System.out.println("Example of findFirst() :");
System.out.println(Arrays.stream(arr_sample1)
.findFirst());
// max()
// It returns the max element in an array
System.out.println("Example of max() :");
System.out.println(Arrays.stream(arr_sample1)
.max());
// min()
// It returns the min element in an array
System.out.println("Example of min() :");
System.out.println(Arrays.stream(arr_sample1)
.min());
// reduce()
// It reduces the array by certain operation
// Here it performs addition of array elements
System.out.println("Example of reduce() :");
System.out.println(Arrays.stream(arr_sample1)
.reduce((x, y)->x + y));
// reduce() have another variation which we will
// see in different example
}
}
输出
These method returns Optional
Example of average() :
OptionalDouble[17.4]
Example of findAny() :
OptionalInt[11]
Example of findFirst() :
OptionalInt[11]
Example of max() :
OptionalInt[55]
Example of min() :
OptionalInt[2]
Example of reduce() :
OptionalInt[348]
但要处理这个OptionalInt和OptionalDouble就变得非常困难了,因此Java提供了将它们转换为双倍和英寸值的方法,这样就可以很容易地重复使用。
import java.util.Arrays;
class GFG_Demo_4 {
public static void main(String[] args)
{
int arr_sample1[] = { 11, 2, 3, 42, 5, 6, 17, 8, 9,
10, 11, 12, 13, 24, 55, 16, 47, 18, 19, 20 };
System.out.println("These method convert Optional to primitive");
// OptionalDouble can be converted to double by using getAsDouble()
// if average doesn't contains any value it throws NoSuchElementException
System.out.println("Example of average() : ");
System.out.println((Arrays.stream(arr_sample1)
.average()
.getAsDouble()));
// OptionalInt can be converted to int by using getAsInt()
System.out.println("Example of findAny() : ");
System.out.println(Arrays.stream(arr_sample1)
.findAny()
.getAsInt());
}
}
输出
These method convert Optional to primitive
Example of average() :
17.4
Example of findAny() :
11
IntStream还提供了一些其他的方法,我们将在不同的文章中讨论这些方法,并将使用流方法的不同变化。
参考资料:
https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html
https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html