Java 8中的原始類型流
1.簡介
Stream API是Java 8中添加的關鍵功能之一。
簡而言之,通過提供聲明性的API,API使我們能夠方便,高效地處理集合和其他元素序列。
2.原始流
流主要用於對象的集合,而不是原始類型。
幸運的是,為了提供一種使用三種最常用的原始類型( int, long
和double
)的方法,標準庫包括三種原始的專用實現: IntStream
, LongStream,
和DoubleStream
。
原始流受到限制的主要原因是裝箱開銷以及在許多情況下為其他原始創建專門的流不是那麼有用。
3.算術運算
讓我們從一些有趣的常用運算方法開始,例如min
, max
, sum
和average:
int[] integers = new int[] {20, 98, 12, 7, 35};
int min = Arrays.stream(integers)
.min()
.getAsInt(); // returns 7
現在,讓我們逐步瀏覽上面的代碼片段,以了解發生了什麼。
我們使用java.util.Arrays.stream(int[])
創建了IntStream
,然後使用min()
方法獲取了最小的整數java.util.OptionalInt
,最後調用getAsInt()
獲得了int
值。
創建IntStream
另一種方法是使用IntStream.of(int…)
。 max()
方法將返回最大的整數:
int max = IntStream.of(20, 98, 12, 7, 35)
.max()
.getAsInt(); // returns 98
下一步–要獲取整數之和,我們只需要調用sum()
方法,就不需要使用getAsInt()
因為它已經以int
值形式返回了結果:
int sum = IntStream.of(20, 98, 12, 7, 35).sum(); // returns 172
我們調用average()
方法來獲取整數值的平均值,並且如我們所見,我們應該使用getAsDouble()
因為它返回類型為double
的值。
double avg = IntStream.of(20, 98, 12, 7, 35)
.average()
.getAsDouble(); // returns 34.4
4.範圍
我們還可以基於範圍創建IntStream
:
int sum = IntStream.range(1, 10)
.sum(); // returns 45
int sum = IntStream.rangeClosed(1, 10)
.sum(); // returns 55
如上面的代碼片段所示,有兩種方法可以創建整數range()
和rangeClosed()
。
區別在於range()
的結尾是獨占的,而rangeClosed()
的結尾是獨占的。
範圍方法僅適用於IntStream
和LongStream
。
我們可以使用範圍作為for-each循環的形式:
IntStream.rangeClosed(1, 5)
.forEach(System.out::println);
將它們用作每個循環替換的優點在於,我們還可以利用並行執行的優勢:
IntStream.rangeClosed(1, 5)
.parallel()
.forEach(System.out::println);
與這些奇特的循環一樣有用,由於某些情況下的簡單性,可讀性和性能,最好還是使用傳統的for循環而不是功能性的循環進行簡單的迭代。
5.裝箱和拆箱
有時我們需要將原始值轉換為其等效的包裝器。
在這種情況下,我們可以使用boxed()
方法:
List<Integer> evenInts = IntStream.rangeClosed(1, 10)
.filter(i -> i % 2 == 0)
.boxed()
.collect(Collectors.toList());
我們還可以將包裝類流轉換為原始流:
// returns 78
int sum = Arrays.asList(33,45)
.stream()
.mapToInt(i -> i)
.sum();
我們始終可以使用mapToXxx
和flatMapToXxx
方法創建原始流。
六,結論
Java Streams是對該語言的非常強大的補充。在這裡,我們幾乎沒有涉及原始流的表面,但是,因為您已經可以使用它們來提高生產率。
而且,與往常一樣,可以在GitHub上找到代碼示例。