JAVA8 - flatMap

将一个单词列表如:["hello","world"] 拆分位一个字符列表返回如:["h","e",.......]

前置:

public static void test1(){
    String[] words = {"hello", "world"};
    Stream<String> stream = Arrays.stream(words);
}

实现方式一:

package com.datastructure.binarytree.btree;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test3 {

    public static void main(String[] args) {
        List<String> words = Arrays.asList("Hello", "world");

        //错误实现方式:
        List<Stream<String>> collect1 = words.stream().
                map(word -> word.split("")).
                map(Arrays::stream).collect(Collectors.toList());
        System.out.println(collect1); //out: [java.util.stream.ReferencePipeline$Head@4dd8dc3, java.util.stream.ReferencePipeline$Head@6d03e736]


        //right
        List<String> collect2 = words.stream().map(word -> word.split(""))
                .flatMap(Arrays::stream)  //返回:Stream<String[]>
                .collect(Collectors.toList());

        System.out.println(collect2); //out: [H, e, l, l, o, w, o, r, l, d]

    }
}

实现方式二:

当使用flatMap 时,你需要提供一个方法,它会为每一个流元素产生一个新的流。正如你所见,这会显得冗长,而且效率略显低下。mapMutil 方法提供了另一种选择。与产生由结果构成的流不同,我们生成结果后将它们传递给一个收集器,即一个实现了Consumer 函数式接口的类的对象。每一个结果都会调用该收集器上的accpet方法。

@Test
public void test1() {
    List<String> words = Arrays.asList("Hello", "world");

    List<Object> objects = words.stream().mapMulti((word, collector) -> {
        Stream.of(word.split("")).forEach(collector::accept);
    }).toList();
    System.out.println(objects);  //[H, e, l, l, o, w, o, r, l, d]

}

练习:

package com.datastructure.binarytree.btree;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test4 {

    /*
     需求1:给定两个数字列表,如何返回所有的数对那?例如给定列表[1,2,3] 和 列表[3,4],应该还返回
     [(1,3),(1,4),(2,3),(2,4),(3,3),(3,4)]。
     */
    public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(1, 2, 3);
        List<Integer> integers1 = Arrays.asList(4, 5);
        
        //写法效果同 嵌套for 循环
        List<int[]> collect = integers.stream().flatMap(i -> integers1.stream().map(j -> new int[]{i, j}))
                .collect(Collectors.toList());

        collect.stream().forEach(i -> System.out.println(Arrays.toString(i)));
        /*
        输出:
        [1, 4]
        [1, 5]
        [2, 4]
        [2, 5]
        [3, 4]
        [3, 5]
         */

    }

    /*
    需求2:扩展上列,只返回 总和 能被3 整除的数对
     */
    public static void method() {
        List<Integer> integers = Arrays.asList(1, 2, 3);
        List<Integer> integers1 = Arrays.asList(4, 5);

        List<int[]> collect = integers.stream().flatMap(i -> integers1.stream().filter(j -> (i + j) % 3 == 0).map(j -> new int[]{i, j}))
                .collect(Collectors.toList());

        collect.stream().forEach(i -> System.out.println(Arrays.toString(i)));
        /*
        [1, 5]
        [2, 4]
         */
    }

    //需求3:列出3个数组的不同组合方式
    private static void method2() {
        List<Integer> integers = Arrays.asList(1, 2, 3);
        List<Integer> integers1 = Arrays.asList(4, 5);
        List<Integer> integers2 = Arrays.asList(6, 7);
        
        //错误实现方式
//        List<Stream<int[]>> collect1 = integers.stream().flatMap(i -> integers1.stream().map(j -> integers2.stream().map(z -> new int[]{i, j, z})))
//                .collect(Collectors.toList());

        List<int[]> collect = integers.stream().flatMap(i -> integers1.stream().flatMap(j -> integers2.stream().map(z -> new int[]{i, j, z})))
                .collect(Collectors.toList());

        collect.stream().forEach(i -> System.out.println(Arrays.toString(i)));
        /*
        [1, 5, 7]
        [2, 4, 6]
        [2, 4, 7]
        [2, 5, 6]
        [2, 5, 7]
        [3, 4, 6]
        [3, 4, 7]
        [3, 5, 6]
        [3, 5, 7]
         */
    }
}
posted @ 2024-01-17 23:07  chuangzhou  阅读(198)  评论(0)    收藏  举报