日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java8新特性stream深入解析

發布時間:2023/12/9 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java8新特性stream深入解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

繼續java8源碼的發燒熱,越看越是有充實的感覺。

數據時代下的產物

Java順應時代的發展推出的高效處理大量數據能力的api,它專注于對集合對象進行各種非常便利、高效的聚合操作,借助于同樣新出現的 Lambda 表達式,極大的提高編程效率和程序可讀性。同時它提供串行和并行兩種模式進行匯聚操作,并發模式能夠充分利用多核處理器的優勢,可以很方便地寫出高性能的并發程序。

Stream可以極大提高Java程序員的生產力,讓程序員寫出高效率、干凈、簡潔的代碼。

核心概念理解

一個流的操作 = 創建流 + 中間操作 + 結果轉換。

  • 創建流:指從集合轉換過濾,數值轉換過濾、I/O轉換、創建等等;
  • 中間操作:指對流中的數據進行聚合,如filter\map\sorted\reduce、distinct等等;
  • 結果轉換:指將流進行輸出,打印、轉換成array、轉換成collection等;
  • Stream重要點:

  • 流是不存儲值的,只是一個管道過程
  • 單個流只能被使用一次,再次被使用報錯
  • 流是支持函數式調用
  • 測試樣例定義

    static List<ICar> cars = new ArrayList<>();static Map<Integer,String> kv = new HashMap<>();public static void init(){for(int i = 1; i <= 10; i++){WeiLaiCar car = new WeiLaiCar();car.setCarWheel(i);cars.add(car);kv.put(i,i+"-value");} }

    源碼深度

    在java.util.stream目錄下可以看出有多種stream可以使用。Stream是支持泛型的對象的流,另外還提供了double\int\long常用數據類型的流,但他們提供的方法基本類似。

    1、流是管道內部單向不可逆操作

    Random random = new Random(); IntStream intStream = random.ints(10); intStream.limit(6).forEach(PrintUtil::printTest); intStream.toArray();

    這里的第二個intStream.toArray()執行會報錯誤:IllegalStateException: stream has already been operated upon or closed,流創建流到結束流單個管道內只能順序一次使用,想要再次使用就得從源頭重新創建流重新開始;

    Random random = new Random(); IntStream intStream = random.ints(10); intStream.limit(6).forEach(PrintUtil::printTest); random.ints(15).toArray();

    2、Stream的串行和并行

    流的計算提供了兩種模式:串行流和并行流,認是創建串行流。

    • 提供流方法parallel()和sequential()在串并流間相互轉換。
    • 在Collection接口上添加了兩個方法stream()\parallelStream(),parallel是并行計算的。這兩個方法的內部實現皆是通過StreamSupport.stream(xx,aa)來實現,該方法的aa參數是boolean代表是否開啟并行流;

    3、collection與stream轉換

    流提供有方法toArray()轉換成數組,也提供了方法collect()轉換為list\set\Collection集合;同時Arrays.stream()方法可以把數組轉換為流。

    //list -> stream Stream<ICar> carStream = cars.parallelStream(); carStream.filter(a -> a.getWheelCount() > 5).map(a-> a.hashCode()+"|"+a.getWheelCount()).forEach(PrintUtil::printTest); //list轉換為并發stream并打印符合條件的對象的hashcode和wheel數量:730140433|8//stream -> list Stream<ICar> tmp = cars.stream(); List<ICar> carList = tmp.collect(Collectors.toList()); carList.forEach(PrintUtil::printTest); //通過collect方法把stream轉換為list并打印對象全稱:com.ts.util.optional.WeiLaiCar@4e515669//array -> stream ICar[] carss = {new WeiLaiCar(1),new WeiLaiCar(2)}; Arrays.stream(carss).filter(a -> a.getWheelCount() >2).forEach(PrintUtil::printTest); //最終輸出8個wheel大于2個的對象,并打印對象全稱:com.ts.util.optional.WeiLaiCar@4dcbadb4//stream -> array Object[] tmps = cars.stream().filter(a ->a.getWheelCount()>7).toArray(); PrintUtil.printTest(tmps.length); //從cars中轉換stream選出wheel大于7個的,轉換為數值最終輸出數量為:3

    4、stream的排序

    默認的排序要求排序對象是自然的有些值,一般dubble\int\long等;其他的類型需要主動定義comparator接口比較邏輯。

    //默認sorted()要求是值natural order,即是自然順序的 cars.stream().map(a->a.getWheelCount()).sorted().forEach(PrintUtil::printTest); //先將對象的int類型的wheel聚合成集合,再使用默認排序(順序)進行打印:1 2 3 4 5 6 ...10//自定義comparator,也可以在對象之間實現Comparator接口 cars.stream().sorted(Comparator.comparingInt(ICar::getWheelCount)).map(a->a.getWheelCount()).forEach(PrintUtil::printTest); //自定義使用ICar的int類型wheel字段順序比較,之后再將對象的wheel字段聚合進行打印:1 2 3 4 5 6 ...10 cars.stream().sorted(Comparator.comparingInt(ICar::getWheelCount).reversed()).map(a->a.getWheelCount()).forEach(PrintUtil::printTest); //自定義使用ICar的int類型wheel字段順序比較后再逆轉,之后再將對象的wheel字段聚合進行打印 //與上面的順序正好相反:10 9 8 7 ... 1

    流包下重要的工具類

  • Collectors 提供了很多 reduction 操作,都是靜態的方法,如聚合成集合或者其他類型,官網例子如下:
  • // Accumulate names into a List List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());// Accumulate names into a TreeSet Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));// Convert elements to strings and concatenate them, separated by commas String joined = things.stream().map(Object::toString).collect(Collectors.joining(", "));// Compute sum of salaries of employee int total = employees.stream().collect(Collectors.summingInt(Employee::getSalary)));// Group employees by department Map<Department, List<Employee>> byDept = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment));// Compute sum of salaries by department Map<Department, Integer> totalByDept = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment,Collectors.summingInt(Employee::getSalary)));// Partition students into passing and failing Map<Boolean, List<Student>> passingFailing = students.stream().collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
  • StreamSupport 是stream的底層創建操作方法實現類,讓我們查看一下Stream類的部分方法源碼:
  • /*** Returns an empty sequential {@code Stream}.** @param <T> the type of stream elements* @return an empty sequential stream*/public static<T> Stream<T> empty() {return StreamSupport.stream(Spliterators.<T>emptySpliterator(), false);}/*** Returns a sequential {@code Stream} containing a single element.** @param t the single element* @param <T> the type of stream elements* @return a singleton sequential stream*/public static<T> Stream<T> of(T t) {return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);}
  • 其他創建stream的方式,通過Stream的靜態方法或者StreamSupport類:
  • Stream<String> stringStream = Stream.of("1","a","c"); stringStream.forEach(PrintUtil::printTest); // 1 a cStream<Integer> integerStream = Stream.empty(); PrintUtil.printTest("count is " + integerStream.count()); //count is 0double[] tm = {22D,1.11D,33D,20.12D,11.02D,9.34D}; DoubleStream doubleStream = StreamSupport.doubleStream(Spliterators.spliterator(tm,0,5,1),true); doubleStream.filter(a -> a < 20).forEach(PrintUtil::printTest); //1.11 11.02

    要主動擁抱新技術的出現

    看著公司年輕的工程師一個比一個年輕,我變的更加努力了。要鞭策自己在項目中多嘗試使用新API各種類和方法以鍛煉自己,這些東西就是需要多用你才能發現區別并提升你的技術能力。

    就算是寫業務的也能寫出不一樣的水平。時常告訴自己去學習,追求進步不要做茫茫的小白。 對于一個工程師來說學習能力是你在這個行業必備的能力。

    測試用例地址:play-java-sample


    作者:Owen Jia

    歡迎關注他的博客:Owen Blog

    堅持寫博客成了我的一種寄托

    轉載于:https://my.oschina.net/timestorm/blog/3009416

    總結

    以上是生活随笔為你收集整理的java8新特性stream深入解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。