国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java8 - Streams flatMap()

這篇具有很好參考價(jià)值的文章主要介紹了Java8 - Streams flatMap()。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


java stream flatmap,【Java - Java 8】,java,flatMap,Stream

官方文檔

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

java stream flatmap,【Java - Java 8】,java,flatMap,Stream


What is flatMap()?

# Stream<String[]>
# Stream<Stream<String>>
# String[][]

[
  [1, 2],
  [3, 4],
  [5, 6]
]

它由一個(gè) 2 級(jí) Stream 或一個(gè)二維數(shù)組組成 。

在 Java 8 中,我們可以使用 flatMap 將上述 2 級(jí) Stream 轉(zhuǎn)換為一級(jí) Stream 或?qū)?二維數(shù)組轉(zhuǎn)換為 一維數(shù)組。

# Stream<String>
# String[]

[1, 2, 3, 4, 5, 6]

簡(jiǎn)言之, flatmap方法讓你把一個(gè)流中的每個(gè)值都換成另一個(gè)流,然后把所有的流連接
起來(lái)成為一個(gè)流。

看一個(gè)簡(jiǎn)單的例子: 使用flatMap找出單詞列表中各不相同的字符
java stream flatmap,【Java - Java 8】,java,flatMap,Stream


Why flat a Stream?

處理包含多個(gè)級(jí)別的 Stream ,比如 Stream<String[]>Stream<List<LineItem>>Stream<Stream<String>> 想 將 2 級(jí) Stream 扁平化為一級(jí),如 Stream<String>Stream<LineItem>,這樣就可以輕松地循環(huán) Stream 并對(duì)其進(jìn)行處理。

來(lái)看個(gè)簡(jiǎn)單的功能實(shí)現(xiàn),以及常犯的一些錯(cuò)誤。

需求: 有 {"a", "b"}, {"c", "d"}, {"e", "f"} 三個(gè)數(shù)組,要求輸出 除去a之后的數(shù)據(jù)

 /**
     * filter out the a and print out all the characters
     */
    private static void filterAndPrintCharacters() {

        String[][] array = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}};

        // convert  array to a stream
        Stream<String[]> stream = Arrays.stream(array);

        // array to a stream [same result]
        Stream<String[]> array1 = Stream.of(array);


        log.info("==========錯(cuò)誤的方式一===============");

        //    x is a String[], not String!
        List<String[]> result = stream.filter(x -> !x.equals("a"))
                .collect(Collectors.toList());

        log.info(String.valueOf(result.size()));
        result.forEach(x -> log.info(Arrays.toString(x)));

        log.info("==========錯(cuò)誤的方式二===============");

        List<String[]> result1 = Arrays.stream(array).filter(x -> {
            for (String s : x) {   // really?
                if (s.equals("a")) {
                    return false;
                }
            }
            return true;
        }).collect(Collectors.toList());

        log.info(String.valueOf(result1.size()));
        result1.forEach(x -> log.info(Arrays.toString(x)));


        log.info("============正確的方式 flatMap=============");

        log.info("============先測(cè)試轉(zhuǎn)換成一維數(shù)組=============");
        // [a, b, c, d, e, f]
        String[] objects = Arrays.stream(array)
                .flatMap(Stream::of)
                .toArray(String[]::new);
        Arrays.stream(objects).forEach(x -> log.info("|---->{}", x));

        log.info("============開(kāi)始處理=============");
        List<String> collect = Arrays.stream(array)
                .flatMap(Stream::of)
                .filter(x -> !x.equals("a"))
                .collect(Collectors.toList());

        collect.forEach(x -> log.info(x));
        log.info("============處理結(jié)束=============");

    }

我們先看看:

[錯(cuò)誤的方式一]

filter(x -> !x.equals("a"))  // x 是數(shù)組 ,而非字符串 

[錯(cuò)誤的方式二]

x -> {
  for (String s : x) {   // really?
         if (s.equals("a")) {
             return false;
         }
     }
     return true;
 }   //  會(huì)把整個(gè) [a, b] 過(guò)濾出去,而非我們想要過(guò)濾的 a 

[正確的方式 ]

// flatMap 將二維數(shù)組轉(zhuǎn)換成意味數(shù)組, 或者可以說(shuō)是從 Stream<String[]> 轉(zhuǎn)換成Stream<String>.

String[][] array = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}};

  // Java 8
  String[] result = Stream.of(array)  // Stream<String[]>
          .flatMap(Stream::of)        // Stream<String>
          .toArray(String[]::new);    // [a, b, c, d, e, f]

  Arrays.stream(objects).forEach(x -> log.info("|---->{}", x));

接下來(lái)我們就可以很輕松地過(guò)濾出來(lái) a了, 就得到了一下最終版本

 List<String> collect = Arrays.stream(array)
                .flatMap(Stream::of)
                .filter(x -> !x.equals("a"))
                .collect(Collectors.toList());

 collect.forEach(x -> log.info(x));

【小結(jié)】

Stream#flatMap 可以將 2 levels Stream 轉(zhuǎn)換成 1 level Stream.

Stream<String[]>      -> flatMap ->	Stream<String>
Stream<Set<String>>   -> flatMap ->	Stream<String>
Stream<List<String>>  -> flatMap ->	Stream<String>
Stream<List<Object>>  -> flatMap ->	Stream<Object>

java stream flatmap,【Java - Java 8】,java,flatMap,Stream


Demo

需求1:Find all books

分析: 使用 stream 將List轉(zhuǎn)換為對(duì)象流,每個(gè)對(duì)象都包含一組書籍,使用flatMap生成包含所有對(duì)象中所有書籍的流。過(guò)濾掉包含單詞cloud的書,并收集一個(gè)Set以便于刪除重復(fù)的書。

 private static void findAllBooks() {

        Developer o1 = new Developer();
        o1.setName("artisan");
        o1.addBook("Java 8 in Action");
        o1.addBook("Spring Boot in Action");
        o1.addBook("Effective Java (3nd Edition)");

        Developer o2 = new Developer();
        o2.setName("小工匠");
        o2.addBook("Spring Cloud");
        o2.addBook("Effective Java (3nd Edition)");

        List<Developer> list = new ArrayList<>();
        list.add(o1);
        list.add(o2);


        // 這....Set of Set...(Set<Set<String>>)咋處理?
        Set<Set<String>> collect = list.stream().map(x -> x.getBook()).collect(Collectors.toSet());

        // 方式一
        Set<String> result = list.stream()
                .map(x -> x.getBook())
                .flatMap(Collection::stream)
                .filter(x -> !x.toLowerCase().contains("cloud"))
                .collect(Collectors.toSet());
        result.forEach(x -> log.info("element:------>{}", x));


        // 方式二
        // 當(dāng)然了,map也可以不用,直接在flatMap中  x->x.getBook().stream()
        Set<String> result1 = list.stream()
                .flatMap(x -> x.getBook().stream())
                .filter(x -> !x.toLowerCase().contains("cloud"))
                .collect(Collectors.toSet());
        result1.forEach(x -> log.info("element:------>{}", x));

    }

當(dāng)然了 有個(gè)內(nèi)部類

@Data
static class Developer {

     private Integer id;
     private String name;
     private Set<String> book;


     public void addBook(String book) {
         if (this.book == null) {
             this.book = new HashSet<>();
         }
         this.book.add(book);
     }

 }

我們來(lái)來(lái)拆解下 【方式一】的處理過(guò)程如下
java stream flatmap,【Java - Java 8】,java,flatMap,Stream
java stream flatmap,【Java - Java 8】,java,flatMap,Stream

java stream flatmap,【Java - Java 8】,java,flatMap,Stream
java stream flatmap,【Java - Java 8】,java,flatMap,Stream

java stream flatmap,【Java - Java 8】,java,flatMap,Stream

java stream flatmap,【Java - Java 8】,java,flatMap,Stream

總結(jié)下每一步的輸出:

java stream flatmap,【Java - Java 8】,java,flatMap,Stream


需求2:Order and LineItems

訂單是一個(gè)采購(gòu)訂單流,每個(gè)采購(gòu)訂單都包含一組行項(xiàng)目,然后使用flatMap生成一個(gè)包含所有訂單中所有行項(xiàng)目的streamStream<LineItem>。此外,還添加了一個(gè)reduce操作來(lái)合計(jì)行項(xiàng)目的總金額 .

  private static void orderAndLineItems() {

        List<Order> orders = findAll();

        //  sum the order's total amount
        // 計(jì)算 order的total 總和
        BigDecimal reduce = orders.stream().map(Order::getTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
        log.info(reduce.toString());

        // sum the line items' total amount
        // 計(jì)算 全部的 line的 price 總和
        
        // 方式一 先 map 再flatMap
        BigDecimal reduce1 = orders.stream()
                .map(Order::getLineItems)
                .flatMap(Collection::stream)
                .map(line -> line.getTotal())
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        // 方式二  直接 flatMap
        BigDecimal reduce2 = orders.stream()
                .flatMap(order -> order.getLineItems().stream())
                .map(line -> line.getTotal())
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        log.info(reduce1.toString());
        log.info(reduce2.toString());


    }

  /**
     * 模擬數(shù)據(jù)
     *
     * @return
     */
    private static List<Order> findAll() {

        LineItem item1 = new LineItem(1, "apple", 1, new BigDecimal("1.20"), new BigDecimal("1.20"));
        LineItem item2 = new LineItem(2, "orange", 2, new BigDecimal(".50"), new BigDecimal("1.00"));
        Order order1 = new Order(1, "A0000001", Arrays.asList(item1, item2), new BigDecimal("2.20"));

        LineItem item3 = new LineItem(3, "monitor BenQ", 5, new BigDecimal("99.00"), new BigDecimal("495.00"));
        LineItem item4 = new LineItem(4, "monitor LG", 10, new BigDecimal("120.00"), new BigDecimal("1200.00"));
        Order order2 = new Order(2, "A0000002", Arrays.asList(item3, item4), new BigDecimal("1695.00"));

        LineItem item5 = new LineItem(5, "One Plus 8T", 3, new BigDecimal("499.00"), new BigDecimal("1497.00"));
        Order order3 = new Order(3, "A0000003", Arrays.asList(item5), new BigDecimal("1497.00"));

        return Arrays.asList(order1, order2, order3);

    }


 @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Order {
        private Integer id;
        private String invoice;
        private List<LineItem> lineItems;
        private BigDecimal total;
    }


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class LineItem {
        private Integer id;
        private String item;
        private Integer qty;
        private BigDecimal price;
        private BigDecimal total;
    }
    

輸出

java stream flatmap,【Java - Java 8】,java,flatMap,Stream


需求3:Splits the line by spaces

讀取一個(gè)文本文件,計(jì)算單詞數(shù)量

文本文件

hello world           Java
hello world Python
hello world Node JS
hello world Rust
hello world Flutter
  @SneakyThrows
    private static void splitLinesBySpaces() {

        Path path = Paths.get("D:\\IdeaProjects\\boot2\\java8review\\src\\main\\java\\com\\artisan\\java8\\stream2\\a.txt");

        //  按行讀取
        Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);

        //  stream of array...hard to process.
        // Stream<String[]> stream = lines.map(line -> line.split(" +"));


        // stream of stream of string....hmm...better flat to one level.
        // Stream<Stream<String>> words = lines.map(line -> Stream.of(line.split(" +")));

        // +、*、|、\等符號(hào)在正則表達(dá)示中有相應(yīng)的不同意義
        // 加號(hào)可用于與字符匹配 1 次或多次。例如,'bre+' 匹配 bre 和 bree,但不匹配 br
        // " +" 匹配空格

        // result a stream of words, good! 方式一
        Stream<String> words = Files.lines(path, StandardCharsets.UTF_8)
                .flatMap(line -> Stream.of(line.split(" +")));
        
        System.out.println(words.count());

        // 方式二
        long count = Files.lines(path, StandardCharsets.UTF_8)
                .map(line -> line.split(" +"))
                .flatMap(line -> Stream.of(line)).count();

        System.out.println(count);

        
    }


需求4: flatMap and primitive type

java stream flatmap,【Java - Java 8】,java,flatMap,Stream

private static void flatMap2PrimitiveType() {

        int[] array = {1, 2, 3, 4, 5, 6};

        //Stream<int[]>
        Stream<int[]> streamArray = Stream.of(array);

        //Stream<int[]> -> flatMap -> IntStream
        IntStream intStream = streamArray.flatMapToInt(x -> Arrays.stream(x));

        intStream.forEach(System.out::println);


        // flatMapToLong -> LongStream
        long[] array2 = {1, 2, 3, 4, 5, 6};

        Stream<long[]> longArray = Stream.of(array2);

        LongStream longStream = longArray.flatMapToLong(x -> Arrays.stream(x));

        System.out.println(longStream.count());

    }

java stream flatmap,【Java - Java 8】,java,flatMap,Stream文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-771863.html

到了這里,關(guān)于Java8 - Streams flatMap()的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java8 函數(shù)式編程stream流

    Java 8 中新增的特性旨在幫助程序員寫出更好的代碼,其中對(duì)核心類庫(kù)的改進(jìn)是很關(guān)鍵的一部分,也是本章的主要內(nèi)容。對(duì)核心類庫(kù)的改進(jìn)主要包括集合類的 API 和新引入的流(Stream),流使程序員得以站在更高的抽象層次上對(duì)集合進(jìn)行操作。下面將介紹stream流的用法。 ?場(chǎng)景

    2024年02月15日
    瀏覽(21)
  • Java8的Stream流的學(xué)習(xí)

    Stream可以由數(shù)組或集合創(chuàng)建,對(duì)流的操作分為兩種: 中間操作,每次返回一個(gè)新的流,可以有多個(gè)。 終端操作,每個(gè)流只能進(jìn)行一次終端操作,終端操作結(jié)束后流無(wú)法再次使用。終端操作會(huì)產(chǎn)生一個(gè)新的集合或值。 stream和parallelStream的簡(jiǎn)單區(qū)分:?stream是順序流,由主線程按

    2024年02月07日
    瀏覽(26)
  • Java8中Stream詳細(xì)用法大全

    Java8中Stream詳細(xì)用法大全

    Java 8 是一個(gè)非常成功的版本,這個(gè)版本新增的Stream,配合同版本出現(xiàn)的Lambda ,給我們操作集合(Collection)提供了極大的便利。Stream流是JDK8新增的成員,允許以聲明性方式處理數(shù)據(jù)集合,可以把Stream流看作是遍歷數(shù)據(jù)集合的一個(gè)高級(jí)迭代器。Stream 是 Java8 中處理集合的關(guān)鍵抽

    2023年04月08日
    瀏覽(31)
  • Java8 Stream流處理樹(shù)形結(jié)構(gòu)數(shù)據(jù)

    參考資料 Java8新特性-使用Stream流遞歸實(shí)現(xiàn)遍歷樹(shù)形結(jié)構(gòu) ID為2,6,11的Menu 是 ID為1的Menu子節(jié)點(diǎn) ID為3,4,5的Menu 是 ID為2的Menu子節(jié)點(diǎn) ?? 注意 是下面這種寫法的一種更簡(jiǎn)單的寫法

    2024年02月01日
    瀏覽(21)
  • Java8 Stream 之groupingBy 分組講解

    本文主要講解:Java 8 Stream之Collectors.groupingBy()分組示例 Collectors.groupingBy() 分組之常見(jiàn)用法 功能代碼: /** ?? ? * 使用java8 stream groupingBy操作,按城市分組list ?? ? */ ?? ?public void groupingByCity() { ?? ??? ?MapString, ListEmployee map = employees.stream().collect(Collectors.groupingBy(Employee::getCi

    2024年02月13日
    瀏覽(25)
  • java8 Stream流常用方法(持續(xù)更新中...)

    java8 Stream流常用方法(持續(xù)更新中...)

    操作對(duì)象 模擬數(shù)據(jù) 操作 打印結(jié)果 打印結(jié)果 注意:異常自己捕捉,就比如這里String轉(zhuǎn)Intger就可能出現(xiàn)NumberFormatException異常 打印結(jié)果 打印結(jié)果 斷點(diǎn)查看 打印結(jié)果 斷點(diǎn)查看 持續(xù)更新中…

    2024年04月28日
    瀏覽(28)
  • Java8 Stream流常見(jiàn)操作--持續(xù)更新中

    Java8 Stream流是一種處理數(shù)據(jù)集合的方式,它可以對(duì)集合進(jìn)行一系列的操作,包括過(guò)濾、映射、排序等,從而實(shí)現(xiàn)對(duì)集合中元素的處理和轉(zhuǎn)換。Stream流是一種惰性求值的方式,只有在需要返回結(jié)果時(shí)才會(huì)執(zhí)行實(shí)際操作,這種方式可以提高程序的性能。 延遲執(zhí)行:Stream流中的操作

    2024年02月11日
    瀏覽(43)
  • Java8的stream之groupingBy()分組排序

    Java8的stream之groupingBy()分組排序

    groupingBy()是Stream API中最強(qiáng)大的收集器Collector之一,提供與SQL的GROUP BY子句類似的功能。 需要指定一個(gè)屬性才能使用,通過(guò)該屬性執(zhí)行分組。我們通過(guò)提供功能接口的實(shí)現(xiàn)來(lái)實(shí)現(xiàn)這一點(diǎn) - 通常通過(guò)傳遞lambda表達(dá)式。 TreeMap默認(rèn)按照key升序排序,collectPlan.descendingMap()可以進(jìn)行降序排

    2024年02月12日
    瀏覽(25)
  • java中flatMap用法

    java中flatMap用法

    ? ? java中map是把集合每個(gè)元素重新映射,元素個(gè)數(shù)不變,但是元素值發(fā)生了變化。而flatMap從字面上來(lái)說(shuō)是壓平這個(gè)映射,實(shí)際作用就是將每個(gè)元素進(jìn)行一個(gè)一對(duì)多的拆分,細(xì)分成更小的單元,返回一個(gè)新的Stream流,新的流元素個(gè)數(shù)增加。 ? ? java官方給出的示例如下: ? ?

    2024年02月02日
    瀏覽(13)
  • JAVA8中l(wèi)ist.stream()的一些簡(jiǎn)單使用

    為函數(shù)式編程而生。對(duì)stream的任何修改都不會(huì)修改背后的數(shù)據(jù)源,比如對(duì)stream執(zhí)行過(guò)濾操作并不會(huì)刪除被過(guò)濾的元素,而是會(huì)產(chǎn)生一個(gè)不包含被過(guò)濾元素的新stream。 stream上的操作并不會(huì)立即執(zhí)行,只有等到用戶真正需要結(jié)果的時(shí)候才會(huì)執(zhí)行。 stream只能被使用一次,一旦遍歷

    2024年02月03日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包