最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Stream的基本概念以及創(chuàng)建方法

 更新時間:2020年08月28日 11:39:30   作者:莊周de蝴蝶  
這篇文章主要介紹了Java Stream的基本概念以及創(chuàng)建方法,幫助大家更好的理解和學(xué)習Java,感興趣的朋友可以了解下

前言

相信很多人(包括我自己),在很長一段時間內(nèi)雖然使用了 JDK 1.8 ,卻從來沒有使用過自1.8開始增加的 Stream 這一強大使用的新特性,本文則將先從如何創(chuàng)建 Stream 開始,逐步去學(xué)會 Stream 的使用。本文不會涉及對流中數(shù)據(jù)的操作,而只討論創(chuàng)建流的幾種方法,以及一些基礎(chǔ)概念,關(guān)于流的實用操作將會在后續(xù)文章中一一介紹。

Stream 與 Collection 的區(qū)別

1.用途與關(guān)注點不同

Collection 主要關(guān)注于對象的存儲方面,通過使用 List 、 Map、Set等等數(shù)據(jù)結(jié)構(gòu),讓數(shù)據(jù)被更好的組織起來,以便于使用。而 Stream 則關(guān)注于對象的操作方面,包含reducemap、filter等等實用的操作。

2.流是懶搜索(Laziness-seeking)的

先看一個例子,考慮一下代碼:

Random random = new Random(29);
random.ints()
   .filter(v -> v > 5 && v < 31)
   .limit(3)
   .forEach(System.out::println);

// output:
//  21
//  22
//  28

代碼首先創(chuàng)建了一個隨機整數(shù)流,然后過濾得到其中在(5, 31)范圍內(nèi)的數(shù),最終得到其中的3個數(shù)并輸出,這里創(chuàng)建的流就是3中所說的無限流,而流在執(zhí)行的過程中一旦得到一個滿足條件的整數(shù)就會加到結(jié)果序列中,并且開始進行下一輪的搜索,直到找到3個滿足的整數(shù)為止。流只會完成所給任務(wù)(找到3個滿足指定范圍的整數(shù)并輸出),不會有額外的操作。

3.流的大小可以是無限的

盡管 Collection 的數(shù)據(jù)量也可以動態(tài)擴展改變,但由于計算機內(nèi)存是有限的,所以其數(shù)據(jù)量大小始終可以看成只能為有限的大小。但 Stream 則不同,由于流是懶加載的,所以當使用limit類似的短路操作時,就可以利用特性2的原因去接收一個無限流。

4.流操作不存在副作用

和 Collection 中的某些操作,例如remove會刪除集合中的元素不同,流不會修改生成流的原有集合中的數(shù)據(jù),例如使用filter時,會產(chǎn)生一個經(jīng)過元素過濾后的新流,而不會修改原集合中的數(shù)據(jù)。

5.流屬于消耗品(Consumable)

不同與 Collection 沒有訪問次數(shù)與使用的限制,一個流在其生命周期中只能被執(zhí)行一次,當執(zhí)行了終端操作(terminal operation,在之后的文章中會具體介紹)后,即使沒有將流關(guān)閉,例如上述代碼中的forEach,也無法再次訪問了(類似迭代器),如下代碼所示,想要再操作,必須重新創(chuàng)建一個流。

IntStream stream = new Random(29).ints();
stream.filter(v -> v > 5 && v < 31)
   .limit(3)
   .forEach(System.out::println);
// 當執(zhí)行了終端操作后再使用,就會出現(xiàn)一下異常提示信息
// java.lang.IllegalStateException: stream has already been operated upon or closed
stream.forEach(System.out::println);

創(chuàng)建流

流可以通過很多種方式被創(chuàng)建,下面進行一一介紹:

1.Collection 家族創(chuàng)建的方式

對于實現(xiàn)了Collection 接口的類,都可以通過stream()和parallelStream()創(chuàng)建對應(yīng)流,如下代碼所示:

List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
// 創(chuàng)建一個普通的流
Stream<Integer> stream = list.stream();
// 創(chuàng)建一個并行流
Stream<Integer> parallelStream = list.parallelStream();

2.數(shù)組家族創(chuàng)建的方式

對于數(shù)組類型的元素,都可以使用Arrays類的stream()創(chuàng)建對應(yīng)的流,如果想獲得并行流則需要使用parallel()方法,如下所示:

IntStream stream = Arrays.stream(new int[]{1, 2, 3});
// 生成流對應(yīng)的并行流
IntStream parallelStream = stream.parallel();

3.Stream家族的工廠方法

通過工廠方法來創(chuàng)建流的方式比較多,可以通過emptyof、concatgenerate、iterate、rangerangeClosed以及builder等方法創(chuàng)建流,下面就通過代碼樣例來一一介紹:

// 產(chǎn)生一個不包含任何元素的流
Stream<Object> stream1 = Stream.empty();

// 由給定元素所生成的流
Stream<Integer> stream2 = Stream.of(1, 2, 3);

// 合并兩個流產(chǎn)生一個新的流
Stream<Object> stream3 = Stream.concat(stream1, stream2);

// 創(chuàng)建一個<無限流>,流中的數(shù)據(jù)是通過調(diào)用所傳函數(shù)產(chǎn)生的
Stream<Double> stream4 = Stream.generate(Math::random);

// 創(chuàng)建一個<無限流>,流中的數(shù)據(jù)由第一個參數(shù)、將
// 第一個參數(shù)作為函數(shù)參數(shù)調(diào)用產(chǎn)生的值以及不斷將
// 函數(shù)調(diào)用得到的值作為參數(shù)繼續(xù)調(diào)用所組成,
// 例如下面會生成1,2,3....的整數(shù)流
Stream<Integer> stream5 = Stream.iterate(1, v -> v + 1);

// 創(chuàng)建范圍為[1, 5)組成的整數(shù)流
IntStream stream6 = IntStream.range(1, 5);

// 創(chuàng)建范圍為[1, 5]組成的整數(shù)流
IntStream stream7 = IntStream.rangeClosed(1, 5);

// 通過流的建造者模式創(chuàng)建流
Stream.Builder<Integer> builder = Stream.builder();
for (int i = 0; i < 10; i++) {
  // add 與 accept 方法均可將元素添加到流中
  // 區(qū)別是 add 無返回值, accept 會返回當前 builder 的 this 對象
  // 底層 add 方法也是調(diào)用了 accept 然后返回 this
  // 因此對于 add 方法可以進行鏈式調(diào)用
  builder.add(i);
  builder.accept(i);
}
Stream<Integer> stream8 = builder.build();

4.IO/NIO家族中的方法

除了兩種獲取lines生成的流外,其它幾種方式都很少使用,這一部分了解即可。

try {
  String dir = System.getProperty("user.dir");
  // 以下兩種方法均是獲取文件中行數(shù)據(jù)組成的流
  Stream<String> stream1 = new BufferedReader(new FileReader(dir + "\\demo.txt")).lines();
  Stream<String> stream2 = Files.lines(Paths.get(dir + "\\demo.txt"));
  // 獲取指定路徑下所有文件/文件夾的路徑組成的流
  Stream<Path> stream3 = Files.list(Paths.get("d:\\temp"));
  // 獲取指定路徑下以及指定最深文件層級內(nèi)(在這里為2)且滿足函數(shù)條件的所有文件/文件夾的路徑組成的流
  Stream<Path> stream4 = Files.find(
    Paths.get("d:\\temp"), 1, (path, basicFileAttributes) -> path.isAbsolute());
  // 獲取指定路徑下以及指定最深文件層級內(nèi)(在這里為2)所有文件/文件夾的路徑組成的流
  Stream<Path> stream5 = Files.walk(Paths.get("d:\\temp"), 2);
} catch (IOException e) {
  e.printStackTrace();
}

5.Random 獲取流的方式

由于直接使用 Random 類生成隨機數(shù)無限流,均為基本數(shù)據(jù)類型組成的流,因此通常還需要使用boxed方法進行裝箱(以前凡是生成的為IntStreamDoubleStream,LongStream均同此),以便可以使用更加豐富的特性。

Random random = new Random();
// 以下三種方式得到的均是隨機數(shù)組成的<無限流>
IntStream stream1 = random.ints();
DoubleStream stream2 = random.doubles();
LongStream stream3 = random.longs();
Stream<Integer> boxedStream = stream1.boxed();

下面就先舉一個具體的實用的例子,在之后的文章中會詳細介紹一些實用操作,這里可以先做了解:

// 對數(shù)組元素進行倒序排序
// 如果不進行裝箱(boxed)處理,則只能使用默認的升序排序方法
// 通過裝箱,則可以通過自定義比較器,實現(xiàn)更加多樣的排序
int[] arr = {1, 5, 4, 6, 3, 9, 4, 5, 6, 4};
int[] reverseArr = Arrays.stream(arr)
             .boxed()
             .sorted(Comparator.reverseOrder())
             .mapToInt(Integer::valueOf)
             .toArray();
// output: [9, 6, 6, 5, 5, 4, 4, 4, 3, 1]
System.out.println(Arrays.toString(reverseArr));

6.其它可以生成流的類

除了以上介紹的幾個主要可以生成流的類之外,還有一些其它不太常見的可以流的類,下面是部分代碼展示:

String s = "1,2,3,4,5,6,7";
// 由分割后的字符串組成的流
// 在這里就是"1", "2", "3", "4", "5", "6", "7"組成的流
Stream<String> stream1 = Pattern.compile(",").splitAsStream(s);
BitSet bitSet = new BitSet();
for (int i = 0; i < 10; i++) {
  if (i % 2 == 0) {
    bitSet.set(i);
  }
}
// 由 bitset 中被設(shè)置為 true 的位下標所組成的流
// 在這里就是0, 2, 4, 6, 8
IntStream stream2 = bitSet.stream();
try {
  String dir = System.getProperty("user.dir");
  JarFile jarFile = new JarFile(dir + "\\demo.jar");
  // 由指定 jar 包中所有文件及文件夾的 JarEntry 對象所組形成的流
  Stream<JarEntry> stream3 = jarFile.stream();
} catch (IOException e) {
  e.printStackTrace();
}

此外還可以通過 StreamSupport工具類進行產(chǎn)生和操作流,由于本文包括之后的文章主要是為了入門和先簡單上手,所以這里不做詳細討論,感興趣的可以自己進行查閱資料。

總結(jié)

本文簡單介紹了 Stream 這個自1.8開始引入的新特性,然后簡單介紹了一些基本概念和流的創(chuàng)建方式,在接下來的文章中還會介紹流的一些實用操作,希望能和大家一起學(xué)會使用 Stream 這個實用的特性,當然本文也難免有錯誤之處,希望得到各位的指正。

以上就是Java Stream的基本概念以及創(chuàng)建方法的詳細內(nèi)容,更多關(guān)于JAVA Stream的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java實現(xiàn)度分秒坐標轉(zhuǎn)十進制度

    Java實現(xiàn)度分秒坐標轉(zhuǎn)十進制度

    隨著技術(shù)的發(fā)展,十進制度因其精確性和便捷性在現(xiàn)代應(yīng)用中越來越受到青睞,下面我們就來看看如何使用Java實現(xiàn)度分秒坐標轉(zhuǎn)十進制度吧
    2024-12-12
  • Java實現(xiàn)截圖小工具的完整代碼

    Java實現(xiàn)截圖小工具的完整代碼

    這篇文章主要介紹了Java實現(xiàn)截圖小工具的完整代碼,用Java的圖形用戶界面GUI技術(shù)寫了一個電腦截圖小工具,本程序代碼簡單,涉及到異常處理,事件處理,圖形用戶界面等,需要的朋友可以參考下
    2022-05-05
  • Java對稱加密算法DES實例詳解

    Java對稱加密算法DES實例詳解

    這篇文章主要介紹了Java對稱加密算法DES,結(jié)合實例形式詳細分析了java DES算法的概念、原理、實現(xiàn)方法與應(yīng)用場景,需要的朋友可以參考下
    2019-09-09
  • 從dubbo zookeeper注冊地址提取出zookeeper地址的方法

    從dubbo zookeeper注冊地址提取出zookeeper地址的方法

    今天小編就為大家分享一篇關(guān)于從dubbo zookeeper注冊地址提取出zookeeper地址的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 淺談java如何生成分享海報工具類

    淺談java如何生成分享海報工具類

    這篇文章主要介紹了淺談java如何生成分享海報工具類,想了解分享海報知識的同學(xué)不要錯過哦
    2021-04-04
  • Java如何讀取配置文件并賦值靜態(tài)變量

    Java如何讀取配置文件并賦值靜態(tài)變量

    這篇文章主要介紹了Java如何讀取配置文件并賦值靜態(tài)變量,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-10-10
  • Mybatis如何分割字符串

    Mybatis如何分割字符串

    這篇文章主要介紹了Mybatis如何分割字符串問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Springmvc nginx實現(xiàn)動靜分離過程詳解

    Springmvc nginx實現(xiàn)動靜分離過程詳解

    這篇文章主要介紹了Springmvc nginx實現(xiàn)動靜分離過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-09-09
  • Java并發(fā)編程之常用的多線程實現(xiàn)方式分析

    Java并發(fā)編程之常用的多線程實現(xiàn)方式分析

    這篇文章主要介紹了Java并發(fā)編程之常用的多線程實現(xiàn)方式,結(jié)合實例形式分析了java并發(fā)編程中多線程的相關(guān)原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下
    2020-02-02
  • Java 在PPT中創(chuàng)建散點圖的實現(xiàn)示例

    Java 在PPT中創(chuàng)建散點圖的實現(xiàn)示例

    本文將以Java代碼示例展示如何在PPT幻燈片中創(chuàng)建散點圖表。文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11

最新評論

南木林县| 永济市| 延安市| 浦北县| 探索| 修武县| 绥德县| 西林县| 崇仁县| 金乡县| 工布江达县| 濮阳市| 深圳市| 平果县| 临泽县| 汉源县| 大荔县| 舟曲县| 靖安县| 太白县| 中宁县| 鄂托克前旗| 隆尧县| 清水县| 伊吾县| 廉江市| 三门峡市| 池州市| 东港市| 重庆市| 道孚县| 木里| 宝清县| 肥东县| 竹溪县| 陈巴尔虎旗| 阿坝| 江达县| 苍山县| 岱山县| 平顶山市|