<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java 8 Stream 閃亮登場!

          共 8884字,需瀏覽 18分鐘

           ·

          2020-10-06 03:32

          Java技術(shù)棧

          www.javastack.cn

          關(guān)注閱讀更多優(yōu)質(zhì)文章



          作者:funnyZpC
          出處:cnblogs.com/funnyzpc/p/10382053.html

          一. Stream(流)是什么,干什么

          Stream是一類用于替代對集合操作的工具類+Lambda式編程,他可以替代現(xiàn)有的遍歷、過濾、求和、求最值、排序、轉(zhuǎn)換等

          二. Stream操作方式

          • 并行方式parallelStream

          • 順序方式Stream

          三. Stream優(yōu)勢

          • Lambda 可有效減少冗余代碼,減少開發(fā)工作量

          • 內(nèi)置對集合List、Map的多種操作方式,含基本數(shù)據(jù)類型處理

          • 并行Stream有效率優(yōu)勢(內(nèi)置多線程)

          四. Stream(流)的基本使用

          • 遍歷forEach
          @Test
          public?void?stream()?{
          ????//操作List
          ????List>?mapList?=?new?ArrayList()?{
          ????????{
          ????????????Map?m?=?new?HashMap();
          ????????????m.put("a",?"1");
          ????????????Map?m2?=?new?HashMap();
          ????????????m2.put("b",?"2");
          ????????????add(m);
          ????????????add(m2);
          ????????}
          ????};
          ????mapList.stream().forEach(item->?System.out.println(item));

          ????//操作Map
          ????Map?mp?=?new?HashMap(){
          ????????{
          ????????????put("a","1");
          ????????????put("b","2");
          ????????????put("c","3");
          ????????????put("d","4");
          ????????}
          ????};
          ????mp.keySet().stream().forEachOrdered(item->?System.out.println(mp.get(item)));
          }
          • 過濾filter
          List?mapList?=?new?ArrayList()?{
          {
          ????add(1);
          ????add(10);
          ????add(12);
          ????add(33);
          ????add(99);
          }
          };
          //mapList.stream().forEach(item->?System.out.println(item));
          mapList?=?mapList.stream().filter(item->{
          return?item>30;
          }).collect(Collectors.toList());
          System.out.println(mapList);
          • 轉(zhuǎn)換map和極值
          @Test
          public?void?trans(){
          ????List?ps?=?new?ArrayList(){
          ????????{
          ????????????Person?p1?=?new?Person();
          ????????????p1.setAge(11);
          ????????????p1.setName("張強");

          ????????????Person?p2?=?new?Person();
          ????????????p2.setAge(17);
          ????????????p2.setName("李思");

          ????????????Person?p3?=?new?Person();
          ????????????p3.setAge(20);
          ????????????p3.setName("John");

          ????????????add(p1);
          ????????????add(p2);
          ????????????add(p3);
          ????????}
          ????};
          ????
          ????//取出所有age字段為一個List
          ????List?sumAge?=?ps.stream().map(Person::getAge).collect(Collectors.toList());
          ????System.out.println(sumAge);
          ????
          ????//取出age最大的那
          ????Integer?maxAge?=sumAge.stream().max(Integer::compare).get();
          ????System.out.println(maxAge);
          }

          class?Person{

          ????private?String?name;
          ????private?Integer?age;

          ????public?String?getName()?{
          ????????return?name;
          ????}

          ????public?void?setName(String?name)?{
          ????????this.name?=?name;
          ????}

          ????public?Integer?getAge()?{
          ????????return?age;
          ????}

          ????public?void?setAge(Integer?age)?{
          ????????this.age?=?age;
          ????}
          }

          五. Stream(流)的效率+ 模擬非耗時簡單業(yè)務(wù)邏輯

          class?Person{

          ????private?String?name;
          ????private?int?age;
          ????private?Date?joinDate;
          ????private?String?label;

          ????public?String?getName()?{
          ????????return?name;
          ????}

          ????public?void?setName(String?name)?{
          ????????this.name?=?name;
          ????}

          ????public?int?getAge()?{
          ????????return?age;
          ????}

          ????public?void?setAge(int?age)?{
          ????????this.age?=?age;
          ????}

          ????public?Date?getJoinDate()?{
          ????????return?joinDate;
          ????}

          ????public?void?setJoinDate(Date?joinDate)?{
          ????????this.joinDate?=?joinDate;
          ????}

          ????public?String?getLabel()?{
          ????????return?label;
          ????}

          ????public?void?setLabel(String?label)?{
          ????????this.label?=?label;
          ????}
          }
          public?class?DataLoopTest?{

          ????private?static?final?Logger?LOG=?LoggerFactory.getLogger(DataLoopTest.class);

          ????private?static?final?List?persons?=?new?ArrayList<>();
          ????static?{
          ????????for(int?i=0;i<=1000000;i++){
          ????????????Person?p?=?new?Person();
          ????????????p.setAge(i);
          ????????????p.setName("zhangSan");
          ????????????p.setJoinDate(new?Date());
          ????????????persons.add(p);
          ????????}
          ????}

          ????/**
          ?????*?for?循環(huán)耗時?===>?1.988
          ?????*?for?循環(huán)耗時?===>?2.198
          ?????*?for?循環(huán)耗時?===>?1.978
          ?????*
          ?????*/
          ????@Test
          ????public?void?forTest(){
          ????????Instant?date_start?=?Instant.now();
          ????????int?personSize?=?persons.size();
          ????????for(int?i=0;i????????????persons.get(i).setLabel(persons.get(i).getName().concat("-"+persons.get(i).getAge()).concat("-"+persons.get(i).getJoinDate().getTime()));
          ????????}
          ????????Instant?date_end?=?Instant.now();
          ????????LOG.info("for?循環(huán)耗時?===>?{}",?Duration.between(date_start,date_end).toMillis()/1000.0);
          ????}

          ????/**
          ?????*??forEach?循環(huán)耗時?===>?1.607
          ?????*??forEach?循環(huán)耗時?===>?2.242
          ?????*??forEach?循環(huán)耗時?===>?1.875
          ?????*/
          ????@Test
          ????public?void?forEach(){
          ????????Instant?date_start?=?Instant.now();
          ????????for(Person?p:persons){
          ????????????p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()));
          ????????}
          ????????Instant?date_end?=?Instant.now();
          ????????LOG.info("forEach?循環(huán)耗時?===>?{}",?Duration.between(date_start,date_end).toMillis()/1000.0);
          ????}

          ????/**
          ?????*??streamForeach?循環(huán)耗時?===>?1.972
          ?????*??streamForeach?循環(huán)耗時?===>?1.969
          ?????*??streamForeach?循環(huán)耗時?===>?2.125
          ?????*/
          ????@Test
          ????public?void?streamForeach(){
          ????????Instant?date_start?=?Instant.now();
          ????????persons.stream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())));
          ????????Instant?date_end?=?Instant.now();
          ????????LOG.info("streamForeach?循環(huán)耗時?===>?{}",?Duration.between(date_start,date_end).toMillis()/1000.0);
          ????}

          ????/**
          ?????*??parallelStreamForeach?循環(huán)耗時?===>?1.897
          ?????*??parallelStreamForeach?循環(huán)耗時?===>?1.942
          ?????*??parallelStreamForeach?循環(huán)耗時?===>?1.642
          ?????*/
          ????@Test
          ????public?void?parallelStreamForeach(){
          ????????Instant?date_start?=?Instant.now();
          ????????persons.parallelStream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())));
          ????????Instant?date_end?=?Instant.now();
          ????????LOG.info("parallelStreamForeach?循環(huán)耗時?===>?{}",?Duration.between(date_start,date_end).toMillis()/1000.0);
          ????}

          }
          • 模擬耗時簡單業(yè)務(wù)邏輯
          public?class?DataLoopBlockTest?{

          ????private?static?final?Logger?LOG=?LoggerFactory.getLogger(DataLoopTest.class);

          ????private?static?final?List?persons?=?new?ArrayList<>();
          ????static?{
          ????????for(int?i=0;i<=100000;i++){
          ????????????Person?p?=?new?Person();
          ????????????p.setAge(i);
          ????????????p.setName("zhangSan");
          ????????????p.setJoinDate(new?Date());
          ????????????persons.add(p);
          ????????}
          ????}

          ????/**
          ?????*?for?循環(huán)耗時?===>?101.385
          ?????*?for?循環(huán)耗時?===>?102.161
          ?????*?for?循環(huán)耗時?===>?101.472
          ?????*
          ?????*/
          ????@Test
          ????public?void?forTest(){
          ????????Instant?date_start?=?Instant.now();
          ????????int?personSize?=?persons.size();
          ????????for(int?i=0;i????????????try?{
          ????????????????Thread.sleep(1);
          ????????????????persons.get(i).setLabel(persons.get(i).getName().concat("-"+persons.get(i).getAge()).concat("-"+persons.get(i).getJoinDate().getTime()));
          ????????????}catch?(Exception?e){
          ????????????????e.printStackTrace();
          ????????????}
          ????????}
          ????????Instant?date_end?=?Instant.now();
          ????????LOG.info("for?循環(huán)耗時?===>?{}",?Duration.between(date_start,date_end).toMillis()/1000.0);
          ????}

          ????/**
          ?????*??forEach?循環(huán)耗時?===>?101.027
          ?????*??forEach?循環(huán)耗時?===>?102.488
          ?????*??forEach?循環(huán)耗時?===>?101.608
          ?????*/
          ????@Test
          ????public?void?forEach(){
          ????????Instant?date_start?=?Instant.now();
          ????????for(Person?p:persons){
          ????????????try?{
          ????????????????Thread.sleep(1);
          ????????????????p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()));
          ????????????}catch?(Exception?e){
          ????????????????e.printStackTrace();
          ????????????}
          ????????}
          ????????Instant?date_end?=?Instant.now();
          ????????LOG.info("forEach?循環(huán)耗時?===>?{}",?Duration.between(date_start,date_end).toMillis()/1000.0);
          ????}

          ????/**
          ?????*??streamForeach?循環(huán)耗時?===>?103.246
          ?????*??streamForeach?循環(huán)耗時?===>?101.128
          ?????*??streamForeach?循環(huán)耗時?===>?102.615
          ?????*/
          ????@Test
          ????public?void?streamForeach(){
          ????????Instant?date_start?=?Instant.now();
          ????????//persons.stream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())));
          ????????persons.stream().forEach(p->{
          ????????????try?{
          ????????????????Thread.sleep(1);
          ????????????????p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()));
          ????????????}catch?(Exception?e){
          ????????????????e.printStackTrace();
          ????????????}
          ????????});
          ????????Instant?date_end?=?Instant.now();
          ????????LOG.info("streamForeach?循環(huán)耗時?===>?{}",?Duration.between(date_start,date_end).toMillis()/1000.0);
          ????}

          ????/**
          ?????*??parallelStreamForeach?循環(huán)耗時?===>?51.391
          ?????*??parallelStreamForeach?循環(huán)耗時?===>?53.509
          ?????*??parallelStreamForeach?循環(huán)耗時?===>?50.831
          ?????*/
          ????@Test
          ????public?void?parallelStreamForeach(){
          ????????Instant?date_start?=?Instant.now();
          ????????//persons.parallelStream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())));
          ????????persons.parallelStream().forEach(p->{
          ????????????try?{
          ????????????????Thread.sleep(1);
          ????????????????p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()));
          ????????????}catch?(Exception?e){
          ????????????????e.printStackTrace();
          ????????????}
          ????????});
          ????????Instant?date_end?=?Instant.now();
          ????????LOG.info("parallelStreamForeach?循環(huán)耗時?===>?{}",?Duration.between(date_start,date_end).toMillis()/1000.0);
          ????????//LOG.info("\r\n===>?{}",JSON.toJSONString(persons.get(10000)));
          ????}

          }

          可以看到在百萬數(shù)據(jù)下做簡單數(shù)據(jù)循環(huán)處理,對于普通for(for\foreach)循環(huán)或Stream(并行、非并行)下,幾者的效率差異并不明顯。

          注意: 在百萬數(shù)據(jù)下,普通for、foreach循環(huán)處理可能比Stream的方式快許多,對于這點效率的損耗,其實lambda表達式對代碼的簡化更大!

          另外,在并行流的循環(huán)下速度提升了一倍之多,當(dāng)單個循環(huán)耗時較多時,會拉大與前幾者的循環(huán)效率 ?(以上測試僅對于循環(huán)而言,其他類型業(yè)務(wù)處理,比如排序、求和、最大值等未做測試,個人猜測與以上測試結(jié)果相似)

          六. Stream(流)注意項

          • 并行Stream不是線程安全的,當(dāng)對循壞外部統(tǒng)一對象進行讀寫時候會造成意想不到的錯誤,這需要留意
          • Stream總是惰性的,原對象是不可以被修改的,在集合處理完成后需要將處理結(jié)果放入一個新的集合容器內(nèi)
          • 普通循環(huán)與Stream(非并行)循環(huán),在處理處理數(shù)據(jù)量比較大的時候效率是一致的,推薦使用Stream的形式
          • 對于List刪除操作,目前只提供了removeIf方法來實現(xiàn),并不能使用并行方式
          • 對于lambda表達式的寫法
          • 當(dāng)表達式內(nèi)只有一個返回boolean類型的語句時候語句是可以簡寫的,例如:
          persons.parallelStream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())));
          • 當(dāng)表達式內(nèi)會有一些復(fù)雜處理邏輯時需要加上大括號,這與初始化List參數(shù)方式大致一致
          try?{
          ????????Thread.sleep(1);
          ????????p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()));
          ????}catch?(Exception?e){
          ????????e.printStackTrace();
          ????}
          });

          七. stream&Lambda表達式常用api方法


          好了,本篇到這里了,如果你想閱讀更多 Java 8 +?系列教程,可以關(guān)注公眾號Java技術(shù)棧回復(fù) java 獲取,我都寫了一大堆了。





          關(guān)注Java技術(shù)棧看更多干貨



          戳原文,獲取精選面試題!
          瀏覽 76
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久艹| 青娱乐人人干 | 免费的尻屄视频 | 天天好逼av | 精品国产一区二区色婷婷 |