国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

我們一起實戰學習Java8 Stream新特性

開發 前端
sorted方法的入參是一個比較器Comparator,這里我們直接使用Comparator.comparing方法構建一個根據價格排序的比較器,并使用reversed方法返回一個降序的比較器。最后我們使用終結方法collect(Collectors.toList())將結果收集到集合當中。

引言

大家好,我是了不起。剛剛不久Java23如期發布,但目前國內市場Java8還是占據著主導地位。今天我將模擬實際工作中的需求,帶領大家學習Java8中的Stream新特性,大家可以收藏起來以防在需要的時候找不到。

實體類聲明

@Getter
@Setter
public class ComputerDTO {
    /**
     * 計算機編號
     */
    private String computerNo;
    /**
     * 品牌
     */
    private String brand;
    /**
     * 價格
     */
    private BigDecimal price;
    /**
     * cpu核數
     */
    private Integer coreQuantity;
    /**
     * 內存GB
     */
    private Integer memory;
    /**
     * 硬盤信息,包含容量和類型,如 "500GB HDD" 或 "256GB SSD"
     */
    private String hardDisk;
    /**
     * 產地
     */
    private String place;
}

場景描述

我暫且充當一下產品經理,現在羅列出了下列需求,基本上覆蓋了日常使用Stream流的大多場景,各位小伙伴可以先行看一看有沒有思路。

經典場景

  1. 篩選出所有品牌為“abc”的電腦,并按價格降序排序。
  2. 計算所有電腦的價格總和。
  3. 找出內存最大的電腦的信息。
  4. 統計硬盤類型為SSD的電腦數量。
  5. 將所有電腦的產地轉換成一個不重復的集合。
  6. 創建一個Map,鍵為品牌,值為該品牌的電腦列表。
  7. 獲取每個品牌的平均價格。
  8. 獲取一個Map,鍵為計算機編號,值為該計算機信息。

組合應用

  1. 篩選出價格低于5000元且CPU核數大于等于4的電腦。
  2. 找出每個品牌中最貴的電腦,并返回一個包含這些電腦的列表。
  3. 統計每個品牌的電腦數量,并按數量降序排序。
  4. 找出所有品牌為“abc”且內存大于等于8GB的電腦,并按CPU核數降序排序。
  5. 統計每個品牌的平均價格,并找出平均價格最高的品牌。
  6. 創建一個Map,鍵為品牌,值為該品牌所有電腦的總價。

經典場景實戰攻克

下面我來帶大家一道一道攻克,并在這個過程中帶大家梳理一下Stream流使用過程中的一些注意事項。

我們假設需要處理的數據是一個ComputerDTO的List,如下:

List<ComputerDTO> computers=getComputers();

Stream流模型的操作很豐富,我們今天將使用到一些常用的方法,這些方法可以被分成兩種。

終結方法:返回值類型不再是Stream類型的方法,不再支持鏈式調用。如count、forEach、collect方法等。

非終結方法:返回值類型仍然是Stream類型的方法,支持鏈式調用。如map、filter、sorted方法等。

場景1

篩選出所有品牌為“abc”的電腦,并按價格降序排序。

List<ComputerDTO> abcComputers = computers.stream()
       .filter(computer -> "abc".equals(computer.getBrand()))
       .sorted(Comparator.comparing(ComputerDTO::getPrice).reversed())
       .collect(Collectors.toList());

首先我們將這個場景拆解成兩個過程,第一個過程是將列表中的所有品牌不為“abc”的電腦過濾掉,這里我們需要使用到filter方法。

filter方法的入參是含一個參數返回結果為boolean類型的函數式接口,這里我們直接使用lambda表達式實現。

需要注意的是filter方法將會保留符合表達式的數據,這里可以和集合的removeIf方法進行對比記憶,并且我們使用stream處理數據并不會改變原集合computers。

第二個過程是將過濾后的結果按照價格降序排序,這里我們使用sorted方法實現。

sorted方法的入參是一個比較器Comparator,這里我們直接使用Comparator.comparing方法構建一個根據價格排序的比較器,并使用reversed方法返回一個降序的比較器。

最后我們使用終結方法collect(Collectors.toList())將結果收集到集合當中。

場景2

計算所有電腦的價格總和。

BigDecimal totalCost = computers.stream()
       .map(ComputerDTO::getPrice)
       .reduce(BigDecimal.ZERO, BigDecimal::add);

這個場景我們需要先將集合中的ComputerDTO對象轉換為價格,因為我們需要的最終結果是一個BigDecimal類型,所以需要先使用map方法對數據進行轉換。

map方法的入參是一個Function函數式接口,下面貼出一張圖幫助大家理解map方法的作用。

圖片圖片

map方法在工作中常常被使用,例如需要根據一個實體類集合獲取一個屬性值集合,通常先使用map方法獲取屬性值,看情況需要可以使用distinct方法去重、filter過濾、sorted方法排序,最后使用collect方法收集起來。

在當前場景中我們需要計算所有電腦的價格總和,所以可以使用reduce終結方法進行匯總。

圖片圖片

場景3

找出內存最大的電腦的信息。

Optional<ComputerDTO> maxMemoryComputer = computers.stream()
       .max(Comparator.comparingInt(ComputerDTO::getMemory));

這個場景簡單粗暴,直接將待處理數據轉成流,然后使用max方法就可以解決,不過需要注意的是max方法返回的數據使用Optional包了一層。

Optional類同樣是Java8提供的,使用isPresent方法可以判斷包含值是否為null,通過get方法可以獲取包含值,如果包含值為null會拋出一個NoSuchElementException異常,所以通常搭配isPresent方法使用。

場景4

統計硬盤類型為SSD的電腦數量。

long ssdCount = computers.stream()
       .filter(computer -> computer.getHardDisk().contains("SSD"))
       .count();

這個場景使用了一個新的終結方法count,count方法用于統計流中元素個數,返回值類型為long類型。

場景5

將所有電腦的產地轉換成一個不重復的集合。

Set<String> places = computers.stream()
       .map(ComputerDTO::getPlace)
       .collect(Collectors.toSet());

這個場景在工作中常常會用到,也是上面提到的map的經典用法,只不過這里將流中數據通過collect(Collectors.toSet())收集到了Set中,利用了Set的特性進行去重,而沒有使用distinct方法進行去重。

這里引申一下,上點難度,如果這里最終需要獲取的是根據產地去重后的ComputerDTO集合呢,使用流的方式又該怎樣實現。

這是工作中另外的一個經典場景,List集合按照對象屬性去重,其實最終也是利用了Set的特性,在Set的構造函數中傳入了自定義比較器!

List<ComputerDTO> newList = computers.stream().collect(Collectors
                .collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ComputerDTO::getPlace)))
                        , ArrayList::new));

這里使用的Collectors.collectingAndThen方法只是將返回結果Set轉化為了List,核心處理就是Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ComputerDTO::getPlace)))。

場景6

創建一個Map,鍵為品牌,值為該品牌的電腦列表。

Map<String, List<ComputerDTO>> computersByBrand = computers.stream()
       .collect(Collectors.groupingBy(ComputerDTO::getBrand));

這個場景也是工作中常常會遇到的場景,對原有數據根據某一個緯度進行分組,然后不同組的數據使用不同的邏輯進行處理。Stream為這個需求也提供了專門的方法Collectors.groupingBy。

場景7

獲取每個品牌的平均價格。

Map<String, Double> averagePrices = computers.stream()
       .collect(Collectors.groupingBy(ComputerDTO::getBrand, Collectors.averagingDouble(c -> c.getPrice().doubleValue())));

這個場景是場景6的進階玩法,根據某一個緯度進行分組,分組后再對數據進行處理。

這里使用的是Collectors.groupingBy兩個參數的重載方法。

場景8

獲取一個Map,鍵為計算機編號,值為該計算機信息。

Map<String, ComputerDTO> computerInfoMap = computers.stream().collect(Collectors.toMap(ComputerDTO::getComputerNo, item -> item));

Map<String, ComputerDTO> computerInfoMap = computers.stream().collect(HashMap::new, (m, v) -> m.put(v.getComputerNo(), v), HashMap::putAll);

這個場景在工作中出現的頻率很高,通常有兩種方法去實現,其中Collectors.toMap方法有一個小坑,大家在使用時需要注意一下。

java8的Collectors.toMap的value不能為null。

如果待處理的數據中value值存在null,則會出現莫名其妙的空指針異常,所以我在工作中往往會使用第二種方式。

組合應用代碼參考

通過上面經典場景的講解,其實我們可以注意到,基本上絕大多數的應用都離不開collect方法,這個方法在流的使用中極為重要,在后續的文章中我也會為大家進一步的講解collect方法,敬請期待!

組合場景就是對經典場景中的一些常用API進行組合應用,所以就不在這里一一贅述,僅為大家提供了參考代碼。

  1. 篩選出價格低于5000元且CPU核數大于等于4的電腦。
List<ComputerDTO> affordableAndPowerful = computers.stream()
       .filter(computer -> computer.getPrice().compareTo(new BigDecimal("5000")) < 0 && computer.getCoreQuantity() >= 4)
       .collect(Collectors.toList());
  1. 找出每個品牌中最貴的電腦,并返回一個包含這些電腦的列表。
Map<String, ComputerDTO> mostExpensivePerBrand = computers.stream()
            .collect(Collectors.groupingBy(ComputerDTO::getBrand,
                    Collectors.collectingAndThen(
                            Collectors.maxBy(Comparator.comparing(ComputerDTO::getPrice)),
                            optional -> optional.orElseThrow(() -> new NoSuchElementException("No computers found for this brand"))
       )
   ));

    List<ComputerDTO> mostExpensiveComputers = new ArrayList<>(mostExpensivePerBrand.values());
  1. 統計每個品牌的電腦數量,并按數量降序排序。
Map<String, Long> brandCounts = computers.stream()
       .collect(Collectors.groupingBy(ComputerDTO::getBrand, Collectors.counting()));

   List<Map.Entry<String, Long>> sortedBrandCounts = brandCounts.entrySet().stream()
       .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
       .collect(Collectors.toList());
  1. 找出所有品牌為“abc”且內存大于等于8GB的電腦,并按CPU核數降序排序。
List<ComputerDTO> abcHighMemoryComputers = computers.stream()
       .filter(computer -> "abc".equals(computer.getBrand()) && computer.getMemory() >= 8)
       .sorted(Comparator.comparingInt(ComputerDTO::getCoreQuantity).reversed())
       .collect(Collectors.toList());
  1. 統計每個品牌的平均價格,并找出平均價格最高的品牌。
Optional<Map.Entry<String, Double>> highestAveragePrice = computers.stream()
       .collect(Collectors.groupingBy(
           ComputerDTO::getBrand,
           Collectors.averagingDouble(c -> c.getPrice().doubleValue())
       ))
       .entrySet().stream()
       .max(Map.Entry.comparingByValue());

   String highestBrand = highestAveragePrice.map(Map.Entry::getKey).orElse(null);
   double highestAverage = highestAveragePrice.map(Map.Entry::getValue).orElse(0.0);
  1. 創建一個Map,鍵為品牌,值為該品牌所有電腦的總價。
Map<String, BigDecimal> totalPricesByBrand = computers.stream()
       .collect(Collectors.groupingBy(
           ComputerDTO::getBrand,
           Collectors.reducing(BigDecimal.ZERO, ComputerDTO::getPrice, BigDecimal::add)
       ));

結語

學會使用java8的Stream新特性,可以極大的減少工作中的代碼量,可以使自己的代碼看起來更整潔,同時很多框架源碼中也大量使用Stream,掌握了它也可以為我們閱讀源碼提供幫助,希望這篇文章可以給大家帶來幫助。

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2022-02-14 10:16:22

Axios接口HTTP

2021-05-19 10:37:16

WebFlux 前置工具

2022-12-09 07:48:10

Java8Stream表達式

2022-12-30 09:24:23

Java8Stream操作

2023-03-28 07:32:37

2023-03-26 12:45:52

Linux內核頭文件

2021-11-26 09:44:42

鏈表節點定位

2021-05-20 07:15:34

RSA-PSS算法簽名

2022-12-01 09:59:57

內核觀測性方法

2025-03-27 02:00:00

SPIJava接口

2022-07-29 08:17:46

Java對象內存

2023-09-29 08:58:38

2023-09-15 06:56:01

RC.NET 6Release

2021-03-18 00:04:13

C# 類型數據

2021-10-11 10:25:33

排列nums數組

2021-12-29 08:27:05

ByteBuffer磁盤服務器

2022-01-17 06:59:40

Grep指令linux

2021-07-28 07:53:20

Github ActiDotnet 應用

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環GolangGo
點贊
收藏

51CTO技術棧公眾號

国产一级特黄a大片99| 亚洲黄色av网址| 精品福利一区| 日韩三级在线免费观看| 1024欧美极品| 94色蜜桃网一区二区三区| 五月婷婷综合色| 日韩亚洲国产精品| 国产精品美女主播在线观看纯欲| 国产精品美女久久久久| 亚洲最新av在线| 在线中文字幕播放| 精品国产网站在线观看| 成人精品久久久| 欧美自拍一区| 久久久久久网址| 香蕉久久一区| 国产午夜精品免费一区二区三区 | xx视频.9999.com| 成人欧美magnet| 亚洲一区二区精品| 欧美大片1688网站| 日韩在线欧美在线| 久久伊人影院| 国内免费久久久久久久久久久| 日韩欧美中文字幕在线视频| 欧美国产日韩一区二区三区| 日韩影视在线观看| 国产精品美女呻吟| 国内自拍一区| 蜜桃成人在线| 国内成人精品2018免费看| 国产在线视频综合| 黄色在线论坛| 日韩最新av在线| free性欧美| 亚洲美女免费精品视频在线观看| 久草一本av| 久久黄色级2电影| 欧美又粗又长又爽做受| 亚洲人成免费| 神马影院午夜我不卡| 葵司免费一区二区三区四区五区| 伊人久久av导航| 99久久免费精品| jizz18欧美| 91久久一区二区| 欧美激情成人动漫| 久久视频免费观看| 日韩精品一卡| 日本一区高清在线视频| 风间由美性色一区二区三区 | 欧美成人自拍| 欧美日韩亚洲综合一区二区三区激情在线 | 欧美视频一区二区三区四区| 9999在线视频| 欧美黑人性生活视频| 91精品国产成人观看| 日韩欧美一区二区在线观看| 91伊人久久大香线蕉| 久草在线看片| 亚洲精品一区二区三区在线观看 | 精品爽片免费看久久| 久久99成人| 国产91社区| 91视频你懂的| 国产高清自拍视频在线观看| 亚洲三级黄色在线观看| 久久电影院7| 波多野结衣与黑人| 亚洲午夜在线电影| 在线天堂资源www在线污| 亲爱的老师9免费观看全集电视剧| 午夜一区在线| 男女羞羞电影免费观看| 欧美一级日韩免费不卡| 97品白浆高清久久久久久| 极品日韩久久| 国产拍欧美日韩视频二区 | 日本二三区不卡| 亚洲精品66| 久久99蜜桃综合影院免费观看| 久久久久久免费网| 影音先锋在线视频| 国产精品国产自产拍高清av水多 | 精品乱码一区| 国产精品每日更新| 爱看av在线| 成人激情免费在线| 99久久99久久综合| 欧美成人三区| 国产精品国模在线| 91一区二区三区在线播放| 五月天婷婷在线视频| 欧美亚洲另类在线| 国产aⅴ精品一区二区三区色成熟| av影片免费在线观看| 国产成人中文字幕| 成人av免费网站| 女囚岛在线观看| 古典武侠综合av第一页| 国产精品乱码一区二区三区软件 | 一本大道熟女人妻中文字幕在线| 欧美久久久久久久久中文字幕| 日韩aaa久久蜜桃av| 久久久天堂国产精品| 欧美在线你懂得| 精品久久精品| 成人羞羞视频免费看看| 欧美夫妻性视频| 91一区二区在线| www.久久.com| 在线观看视频黄色| 亚洲成人黄色在线| 久久久噜噜噜久久狠狠50岁| porn视频在线观看| 欧美亚洲另类在线| 亚洲同性同志一二三专区| 亚洲欧美日本国产| www.四虎成人| 欧美美最猛性xxxxxx| 成人三级伦理片| 国产亚洲欧美日韩精品一区二区三区 | 国产精品成人**免费视频| 玖玖精品在线视频| 亚洲第一精品自拍| 日韩不卡免费视频| 黄色成人在线观看| 久久偷窥视频| 色88888久久久久久影院| 国产欧美黑人| 免费男同深夜夜行网站| 色综合久久悠悠| 91丝袜呻吟高潮美腿白嫩在线观看| 国产三级在线看| 91豆花精品一区| 中文字幕制服丝袜一区二区三区 | 清纯唯美激情亚洲| 一卡二卡三卡视频| www日韩欧美| 久久午夜免费电影| 欧美.com| 国产剧情av在线| 成人福利视频网| 色婷婷久久久亚洲一区二区三区| 欧美精品国产一区| av激情在线| 国产香蕉一区二区三区| 色婷婷综合久久久久中文字幕1| 99re成人精品视频| 午夜欧洲一区| 国产人成在线视频| 色综合电影网| 操91在线视频| 午夜日韩在线电影| 欧美专区一区二区三区| 欧美日韩精品一区二区三区视频| 国产免费毛卡片| 国产91九色视频| 91激情五月电影| 久久精品久久综合| 91成人在线网站| 一级香蕉视频在线观看| 狠狠综合久久av| 在线播放亚洲激情| 亚洲国产一二三| 久久国产日韩| 成人自拍视频| 欧美女子与性| 加勒比海盗1在线观看免费国语版| 久久久久久久色| 欧美日韩中文国产| av成人动漫在线观看| 国产精品久久久乱弄| 亚洲伊人av| а√天堂www在线а√天堂视频| 久久婷婷人人澡人人喊人人爽| www.日本久久久久com.| 日韩欧美在线网址| 免费在线观看一区二区三区| 都市激情久久| 成人短视频在线| 天天激情综合| 日韩电影在线播放| 欧美肥婆姓交大片| 欧美三级蜜桃2在线观看| 成人av免费观看| 日韩一区二区在线| 岛国av在线播放| 91午夜在线| 欧美一级免费播放| 国产精品日韩高清| 97精品在线观看| 日韩第一页在线| 精品日韩美女的视频高清| 成人av网在线| 久久不射中文字幕| 九九视频精品全部免费播放| 国产成人福利夜色影视| av在线看片|