成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Java 8之stream介紹和使用

gxyz / 2673人閱讀

摘要:使用我們來(lái)看下面這段代碼,里面有一個(gè)屬性代表菜品的卡路里值,現(xiàn)在的需求是按卡路里對(duì)菜品進(jìn)行排序再返回菜名,并且要求卡路里的值大于。

前言:

在實(shí)際開(kāi)發(fā)中經(jīng)常需要獲取各種各樣不同格式的數(shù)據(jù),因?yàn)閿?shù)據(jù)庫(kù)的表結(jié)構(gòu)是一開(kāi)始就設(shè)計(jì)好的所以很多時(shí)候我們不得不先從數(shù)據(jù)庫(kù)里或其他地方獲得數(shù)據(jù)后再根據(jù)需求去一層一層的篩選數(shù)據(jù),在Java 8之前的做法不外乎就是各種List、Set一起上,各種循環(huán)判斷。如果只是簡(jiǎn)單的需求還好說(shuō),循環(huán)個(gè)一兩次再判斷一下就可以解決,但是需求復(fù)雜的話就會(huì)寫(xiě)出很復(fù)雜的代碼出來(lái),時(shí)間久了后不僅自己看不懂,而且因?yàn)榇a太復(fù)雜測(cè)試的時(shí)候不敢保證覆蓋到所有的地方,萬(wàn)一代碼到了線上出問(wèn)題,不僅不好改還可能影響到以前的功能,而在Java 8中就提供了新的特性stream,專(zhuān)門(mén)用于對(duì)集合中的數(shù)據(jù)進(jìn)行篩選、分類(lèi)等操作,下面我們就會(huì)介紹stream的使用。

stream使用:

我們來(lái)看下面這段代碼,Dish里面有一個(gè)屬性calories代表菜品的卡路里值,現(xiàn)在的需求是按卡路里對(duì)菜品進(jìn)行排序再返回菜名,并且要求卡路里的值大于400。我們可以看到下面的操作非常繁瑣,先篩選出卡路里大于400的放入集合中,然后對(duì)這個(gè)集合進(jìn)行排序,最后循環(huán)這個(gè)集合把名字放入一個(gè)新的集合,這是一個(gè)很常見(jiàn)的代碼,在Java 8之前都是這么寫(xiě)的,但是這還只是對(duì)一個(gè)屬性的篩選、排序就這么繁瑣了,如果是多個(gè)屬性會(huì)更加麻煩,下面我們就看看用stream是怎么實(shí)現(xiàn)的。

//將卡路里低于400的對(duì)象都放到集合中
List lowCaloricDishes = new ArrayList<>();
    for(Dish d: menu){
        if(d.getCalories() < 400){
            lowCaloricDishes.add(d);
        }
    }

//把這個(gè)集合排序
Collections.sort(lowCaloricDishes, new Comparator() {
    public int compare(Dish d1, Dish d2){
        return Integer.compare(d1.getCalories(), d2.getCalories());
    }
});

//再新建一個(gè)String類(lèi)型的集合來(lái)存放菜名
List lowCaloricDishesName = new ArrayList<>();
for(Dish d: lowCaloricDishes){
    lowCaloricDishesName.add(d.getName());
}

這是Java 8中stream的用法,我們會(huì)發(fā)現(xiàn)這段代碼寫(xiě)起來(lái)非常舒服,首先調(diào)用stream()方法獲取了集合menu的流,然后調(diào)用了filter方法來(lái)篩選出卡路里超過(guò)400的元素,接著調(diào)用了sorted方法對(duì)篩選出來(lái)的元素進(jìn)行排序,再調(diào)用map方法把篩選出來(lái)的元素里面的name屬性抽出來(lái)作為一個(gè)新的流,最后一步則是調(diào)用collect方法把存放name的流轉(zhuǎn)為List格式返回,得到的結(jié)果和上面一模一樣,但是整個(gè)步驟一目了然,先做什么后做什么,非常清晰,這就是stream的用法。

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;

List menu = ...

List lowCaloricDishesName = menu.stream()
    //篩選出卡路里大于400的
    .filter(d -> d.getCalories() < 400)
    //按卡路里值排序
    .sorted(comparing(Dish::getCalories))
    //抽取名字屬性創(chuàng)建一個(gè)新的流
    .map(Dish::getName)
    //這個(gè)流按List類(lèi)型返回
    .collect(toList());
stream的定義:

講到這里大家可能會(huì)產(chǎn)生疑惑,流到底是什么,為什么它可以進(jìn)行這樣的操作。簡(jiǎn)單來(lái)說(shuō)流其實(shí)就是 “從支持?jǐn)?shù)據(jù)處理操作的源生成的元素序列” ,這句話到底是什么意思呢?下面我們來(lái)看看流的各種特性就明白了。

元素序列,可以通過(guò)流訪問(wèn)到特定類(lèi)型的一組有序的值,就像我們通過(guò)集合訪問(wèn)這些數(shù)據(jù)一樣,只不過(guò)集合是為了存儲(chǔ)數(shù)據(jù),而流則注重與對(duì)數(shù)據(jù)的計(jì)算和處理。

源,流可以會(huì)從一個(gè)數(shù)據(jù)源那里獲取數(shù)據(jù)并生成流,例如上面講的從集合中獲取,生成的流里面的元素和數(shù)據(jù)源里的一致。

數(shù)據(jù)處理操作,就像第一條里說(shuō)的,流是注重與對(duì)數(shù)據(jù)的計(jì)算和處理,所以它有很多不同的方法可以對(duì)數(shù)據(jù)進(jìn)行操作,例如篩選、分類(lèi)、排序等等。

流水線,顧名思義,流的很多操作都會(huì)返回一個(gè)新的流,所以我們上面可以使用連綴的方式調(diào)用那些方法,其實(shí)每個(gè)操作都是基于它前面的那個(gè)操作返回的流進(jìn)行的。

我們來(lái)看下面的這段代碼和它的流程圖。它一開(kāi)始從menu這個(gè)集合中獲取到了流,流里面的數(shù)據(jù)和集合是相同的,然后調(diào)用filter方法之后篩選出符合條件的元素組成一個(gè)新的流傳遞給了map方法,然后map方法又從這個(gè)流里面把元素的名字取出來(lái)組成一個(gè)新流傳遞給limit方法,limit方法則只取了前3個(gè)組成一個(gè)流傳遞給collect方法然后返回一個(gè)List,這就是流的工作原理

List list = menu.stream()
    //篩選出卡路里高于300的元素
    .filter(d -> d.getCalories() > 300)
    //獲取名字組成的流
    .map(Dish::getName)
    //只取前3個(gè)
    .limit(3)
    //返回List格式
    .collect(toList());
System.out.println(list );

stream只能遍歷一次:

流和集合不一樣,集合可以想遍歷多少次就遍歷多少次,但是流只能遍歷一次,如果你做了下面這樣的操作,那代碼會(huì)拋出一個(gè)java.lang.IllegalStateException異常,流已被操作或關(guān)閉。

List title = Arrays.asList("Java8", "In", "Action");
Stream s = title.stream();
s.forEach(System.out::println);
s.forEach(System.out::println);
stream的兩種操作:

還是繼續(xù)看這段代碼,其中filter、maplimit操作被稱(chēng)為 中間操作中間操作 會(huì)返回一個(gè)新的流,而collect則被稱(chēng)為 終端操作 ,只有終端操作才會(huì)讓整個(gè)流執(zhí)行并關(guān)閉,也就是說(shuō)只有當(dāng)collect被執(zhí)行時(shí)filter、maplimit才會(huì)被執(zhí)行,上面講到流只能遍歷一次就是因?yàn)?b>forEach就是一個(gè)終端操作,執(zhí)行完后就關(guān)閉流了。

List list = menu.stream()
    //篩選出卡路里高于300的元素
    .filter(d -> d.getCalories() > 300)
    //獲取名字組成的流
    .map(Dish::getName)
    //只取前3個(gè)
    .limit(3)
    //返回List格式
    .collect(toList());

以上就是stream的基本使用方法了,當(dāng)然它的功能還遠(yuǎn)遠(yuǎn)不止這些,后面我們還會(huì)講到篩選、分組、查找等更強(qiáng)大的操作。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76443.html

相關(guān)文章

  • Top stackoverflow 問(wèn)答系列Java 8 Stream 篇 (一)

    摘要:從發(fā)布到現(xiàn)在,已有三年多了,也得到了廣泛的應(yīng)用,但似乎里面最重要的特性和對(duì)很多人來(lái)說(shuō)還是很陌生。想通過(guò)介紹一些實(shí)際的問(wèn)題和答案來(lái)講解在現(xiàn)實(shí)開(kāi)發(fā)中我們可以通過(guò)和可以做些什么,以及什么是正確的姿勢(shì)。 從Java 8 2014 發(fā)布到現(xiàn)在,已有三年多了,JDK 8 也得到了廣泛的應(yīng)用,但似乎Java 8里面最重要的特性:Lambdas和Stream APIs對(duì)很多人來(lái)說(shuō)還是很陌生。想通過(guò)介紹...

    z2xy 評(píng)論0 收藏0
  • Java 8stream進(jìn)階

    摘要:獲取每個(gè)元素的字符串長(zhǎng)度放入新流中,然后轉(zhuǎn)為類(lèi)型。歸約歸約就是把整個(gè)流歸約成一個(gè)值的操作,比如求集合中最大的元素所有元素值的和之類(lèi)的操作。 前言: 上一篇文章 Java 8之stream介紹和使用 中講解了stream的定義和用法,簡(jiǎn)單介紹幾個(gè)最基本最常用的方法,其實(shí)stream還有更強(qiáng)大的功能,這篇文章就會(huì)給大家介紹stream的進(jìn)階用法。 篩選: 在上一篇文章中我們介紹了使用fi...

    Jaden 評(píng)論0 收藏0
  • Java 8數(shù)值流使用構(gòu)建流的方式

    摘要:數(shù)值流的使用想要使用數(shù)值流其實(shí)很簡(jiǎn)單,只需要調(diào)用方法就可以獲得一個(gè)數(shù)值流了,我們會(huì)發(fā)現(xiàn)數(shù)值流有更多的封裝好的計(jì)算方法,更加方便我們對(duì)數(shù)值的計(jì)算。運(yùn)行結(jié)果有時(shí)候我們可能會(huì)想將數(shù)值流轉(zhuǎn)換回原來(lái)的流,我們可以調(diào)用方法。 數(shù)值流: 數(shù)值流,顧名思義就是專(zhuān)門(mén)用來(lái)操作基礎(chǔ)數(shù)據(jù)類(lèi)型的流,那它的作用是什么呢?先看下面的代碼。這段代碼是獲取集合每個(gè)對(duì)象的num字段的值,然后求所和。得出的結(jié)果是15,看上...

    Tychio 評(píng)論0 收藏0
  • Java 8stream實(shí)際應(yīng)用

    摘要:前言在前面的之介紹和使用和之進(jìn)階中講了的使用方式和一些常用的方法,這篇文章就來(lái)演示一下的實(shí)際應(yīng)用。實(shí)際應(yīng)用先創(chuàng)建一個(gè)訂單類(lèi)和商品類(lèi),每個(gè)訂單都有年份商品數(shù)量和商品對(duì)象屬性,而商品類(lèi)里面則包含了名字和價(jià)格屬性。 前言: 在前面的 Java 8之stream介紹和使用 和 Java 8之stream進(jìn)階 中講了stream的使用方式和一些常用的方法,這篇文章就來(lái)演示一下stream的實(shí)際應(yīng)...

    jonh_felix 評(píng)論0 收藏0
  • 樂(lè)字節(jié)-Java8新特性Stream流(上)

    摘要:需要注意的是很多流操作本身就會(huì)返回一個(gè)流,所以多個(gè)操作可以直接連接起來(lái),如下圖這樣,操作可以進(jìn)行鏈?zhǔn)秸{(diào)用,并且并行流還可以實(shí)現(xiàn)數(shù)據(jù)流并行處理操作。為集合創(chuàng)建并行流。 上一篇文章,小樂(lè)給大家介紹了《Java8新特性之方法引用》,下面接下來(lái)小樂(lè)將會(huì)給大家介紹Java8新特性之Stream,稱(chēng)之為流,本篇文章為上半部分。 1、什么是流? Java Se中對(duì)于流的操作有輸入輸出IO流,而Jav...

    dingda 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<