国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Upgrading to Java 8——第四章 The Stream API

2019-11-14 23:15:59
字體:
來源:轉載
供稿:網友
Upgrading to java 8——第四章 The Stream API

  在這章中我們將學習Stream API,在JDK 8 中的一項新的特性。為了理解這一章的主題,你需要知道如何使用Lambda表達式和java.util.function里的預定義的函數式接口。

  一個Stream 類似于一個管道,但它里面運輸的不是水和石油,而是把數據從源頭運輸到目的地。根據傳遞的方式,一個stream可以是并行和并發的。并行的stream運行在多核的CPU的機器上會很有用。

  乍一看,一個stream就像是一個集合容器,但是,它不是一個數據結構用來存儲對象,它只是負責移動對象,所以,你不能把它想象成集合對象那樣往它里面添加數據。

  使用stream的主要原因是它支持并行和并發的聚合操作。例如,你可以非常容易地從stream里面過濾,排序或映射元素。

  Stream API的不同的類型在java.util.stream包中。其中Stream接口是這里面最常用的stream類型。 一個Stream可以傳遞任何類型的對象,同時也有幾個特殊化的Stream:IntStream, LongStream and DoubleStream。他們都來源于BaseStream。

  下面的表格展示了一些在Stream接口中常見的方法:

方法  描述
concat懶加載的方式連接兩個stream。返回一個新的stream,他的元素包括兩個stream的所有元素。第一個stream的元素后面緊跟著第二個stram的元素。
count返回stream里面元素的個數。
empty創建并返回一個空的stream。
filter在stream所有的元素中根據給定的斷言接口返回一個新的stream。
forEach給stream每個元素執行一個操作。
limit從當前的stream中根據指定最大元素的個數返回一個新的stream。
map返回包含了應用于stream的元素的給定的方法的的結果的stream。
max根據比較器返回stream中最大的元素。
min根據比較器返回stream中最小的元素。
of返回一個已經給定了值的stream。
reduce在stream上使用唯一ID和累加器執行遞減操作。
sorted返回一個新的使用自然排序的stream。
toArray返回一個包含stream所有元素的數組。

有些stream的方法執行中間過程的操作,有的執行最終的操作。中間過程的操作會把一個stream傳輸到另一個stream中。像filter,Map,sorted等這些方法。

執行最終操作的方法會產生結果或是其他的影響。例如,count,forEach就是執行的最終結果的操作。

中間過程的操作屬于懶加載的方式,他不會真正的執行,只有是執行最終結果的才會真正在源上開始計算。

創建和獲取一個Stream

你可以使用Stream中靜態的of方法來創建一個連續的stream。例如,下面的例子就是創建了一個包含三個Integer類型元素的stream。

  Stream<Integer> stream = Stream.of(100, 200, 300);

或者,給of方法傳遞一個數組:

  String[] names = {"Bart", "Lisa", "Maggie"};  Stream<String> stream = Stream.of(names);

現在java.util.Arrays 幫助類已經有了method方法用來轉換一個數組給stream。例如,你可以重寫上面的代碼,使用Arrays類創建一個stream。

  String[] names = {"Bart", "Lisa", "Maggie"};  Stream<String> stream = Arrays.stream(names);

另外,在java.util.Collectiond接口中也有個了默認的stream和parallelStream方法分別用來返回一個順序的stream和并行的stream。簽名如下:

  default java.util.stream.Stream<E> stream()  default java.util.stream.Stream<E> parallelStream()

多虧了Collection接口中的這些方法,從List或Set中獲取stream簡直小菜一碟。

除此而外,在java.nio.file.Files類中提供了兩個返回Stream<Path>的方法:list和walk。list方法返回一個指定路徑的入口的泛型為Path的stream。walk方法遍歷了給定路徑下入口里所有的文件并作為stream返回。

Files 也包含了lines方法返回泛型為String的stream的所有行的文本。

看下面的例子。

import java.io.IOException;import java.nio.file.FileVisitOption;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.stream.Stream;public class ObtainStreamDemo {    public static void main(String[] args) throws IOException {    Path path = Paths.get(".");        // use list method.    Stream<Path> list = Files.list(path);    list.forEach(System.out::PRintln);    list.close();        System.out.println("===========================================");        // use walk method.    Stream<Path> walk = Files.walk(path, FileVisitOption.FOLLOW_LINKS);    walk.forEach(System.out::println);    walk.close();        }}

連接兩個stream

在Stream接口中提供了concat方法用來以懶加載的方式連接兩個stream。這個方法返回一個新的stream,它的元素是兩個stream的所有元素,并且第二個stream的元素接在第一個stream元素的后面。

看下面的例子。

import java.util.stream.Stream;public class StreamConcatDemo {    public static void main(String[] args) {    Stream<String> stream1 = Stream.of("January", "Christie");    Stream<String> stream2 = Stream.of("Okanagan", "Sydney", "Alpha");    Stream.concat(stream1, stream2).sorted().forEach(System.out::println);    }}

需要注意的是,此方法不會剔除重復的元素,如果有相同的元素,都一并連接在一個新的stream中。

過濾。

當你從stream中基于一定的條件過濾該stream并返回一個新的包含選定的元素的stream。你可以在Stream對象上調用filter方法,并傳遞一個predicate函數式接口,由它來決定哪些元素包含在新的stream中。

filter方法的簽名如下:

  Stream<T> filter(java.util.function.Predicate<? super T> predicate)

下面的例子,從exapmle.txt中讀取文件,并過濾掉注釋行(已“#”開頭的)和空白行。

public class StreamFilterDemo1 {    public static void main(String[] args) {        Predicate<String> notCommentOrEmptyLine                = (line) -> line.trim().length() > 0                && !line.trim().startsWith("#");        try (FileReader fr = new FileReader("example.txt");                BufferedReader br = new BufferedReader(fr)) {            Stream<String> lines = br.lines();            lines.filter(notCommentOrEmptyLine)                    .forEach(System.out::println);        } catch (IOException e) {            e.printStackTrace();        }    }}

example.txt:

# Set path so it includes user's private bin if it existsif [ -d "$HOME/bin" ] ; then    PATH="$HOME/bin:$PATH"fi

執行結果如下:if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH"fi

第二個例子是使用stream實現在你機器上的文件搜索。為了精確些,代碼只顯示在給定的目錄和子目錄下后綴名為java的文件。

import java.io.IOException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.stream.Stream;public class StreamFilterDemo2 {    public static void main(String[] args) {        // find all java files in the parent directory and        // all its subdirectories        Path parent = Paths.get("..");        try {            Stream<Path> list = Files.walk(parent);            list.filter((Path p) -> p.toString().endsWith(".java"))                    .forEach(System.out::println);        } catch (IOException ex) {            ex.printStackTrace();        }    }}

StreamFilterDemo2 類開始從當前目錄的父目錄開始執行,它傳遞了Path給Files.walk方法去獲取泛型為Paths的stream,接著根據predicate接口只包含后綴名為.java的文件,并用forEach遍歷打印。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宜良县| 榆林市| 浦城县| 德惠市| 夹江县| 原阳县| 尉犁县| 漳州市| 延长县| 黑龙江省| 屯昌县| 密山市| 德钦县| 漠河县| 临城县| 会同县| 泽库县| 澄迈县| 清水县| 潜山县| 三穗县| 渑池县| 定兴县| 浑源县| 柳州市| 太湖县| 云林县| 栖霞市| 蓬安县| 阳西县| 江油市| 三门峡市| 宜州市| 广昌县| 许昌县| 灵寿县| 南平市| 阳东县| 安义县| 紫阳县| 夏河县|