1. 程式人生 > >第2篇 stream -- 對映(map or flatmap)

第2篇 stream -- 對映(map or flatmap)

/**
 * 對映:
 * 一個非常常見的資料處理套路就是從某些物件中選擇資訊。比如在SQL裡,你可以從表中選
 * 擇一列。Stream API也通過map和flatMap方法提供了類似的工具。
 */
public class Demo2 {
    public static void main(String[] args) {
//        methord01();
//        methord02();
//        methord03();
//        methord04();
        methord05();
    }

    /**
     * 對流中每一個元素應用函式:
     * 流支援map方法,它會接受一個函式作為引數。這個函式會被應用到每個元素上,並將其映
     * 射成一個新的元素:
     */
    public static void methord01() {
        List<Dish> menues = Arrays.asList(new Dish("rice", true, 12, Dish.Type.FISH), new Dish("meat", false, 12, Dish.Type.FISH), new Dish("dog", true, 12, Dish.Type.FISH));
        //提取流中菜餚的名稱;因為getName方法返回一個String,所以map方法輸出的流的型別就是Stream<String>
        Set<String> nameSet = menues.stream().map(Dish::getName).collect(Collectors.toSet());
        System.out.println(nameSet.toString());
        //給定一個單詞列表,你想要返回另一個列表,顯示每個單詞中有幾個字母
        List<String> words = Arrays.asList("Java 8", "Lambdas", "In", "Action");
        List<Integer> wordsLengthList = words.stream().map(String::length).collect(Collectors.toList());
        System.out.println(wordsLengthList.toString());
        //如果你要找出每道菜的名稱有多長
        List<Integer> nameLengthSet = menues.stream().map(Dish::getName).map(String::length).collect(Collectors.toList());
        System.out.println(nameLengthSet.toString());


    }

    /**
     * 流的扁平化:
     * 你已經看到如何使用map方法返回列表中每個單詞的長度了。讓我們拓展一下:對於一張單
     * 詞表, 如何返回一張列表, 列出裡面各不相同的字元呢? 例如, 給定單詞列表
     * ["Hello","World"],你想要返回列表["H","e","l", "o","W","r","d"]。
     */
    public static void methord02() {
        String[] arrayOfWords = {"Goodbye", "World"};
        List<String> wordsList = Arrays.asList(arrayOfWords);
        //錯誤一:word -> word.split("") 返回值是一個Stream<String[]>  故結果集為List<String[]> words;有問題吧?哈哈
        List<String[]> words = wordsList.stream().map(word -> word.split("")).distinct().collect(Collectors.toList());
        //錯誤二:我們需要想讓map返回一個Stream<String>;List<String>-->Stream<String>-->Stream<String[]>->Stream<Stream<String[]>>--->List<Stream<String>>
        Stream<String> wordsStream = Arrays.stream(arrayOfWords);//流的整合
        List<Stream<String>> collect = wordsList.stream().map(word -> word.split("")).map(Arrays::stream).distinct().collect(Collectors.toList());
        //正確:使用flatMap方法的效果是,各個陣列並不是分別對映成一個流,而是對映成流的內容。所
        //有使用map(Arrays::stream)時生成的單個流都被合併起來,即扁平化為一個流;Stream<String>;List<String>-->Stream<String>-->Stream<String[]>->Stream<String>--->List<String>
        List<String> wordsSet = wordsList.stream().map(word -> word.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
        System.out.println(wordsSet);

    }

    /**
     * 測試:
     * 給定一個數字列表,如何返回一個由每個數的平方構成的列表呢?例如,給定[1, 2, 3, 4,
     * 5],應該返回[1, 4, 9, 16, 25]。
     */
    public static void methord03() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> result = numbers.stream().map(number -> number * number).collect(Collectors.toList());
        System.out.println(result.toString());
    }

    /**
     * 給定兩個數字列表,如何返回所有的數對呢?例如,給定列表[1, 2, 3]和列表[3, 4],應
     * 該返回[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]。
     */
    public static void methord04() {
        List<Integer> numbers1 = Arrays.asList(1, 2, 3);
        List<Integer> numbers2 = Arrays.asList(3, 4);
        List<Integer[]> collect = numbers1.stream().flatMap(i -> numbers2.stream().map(j -> new Integer[]{i, j})).collect(Collectors.toList());
        for (Integer[] numerr :
                collect) {
            System.out.println(Arrays.asList(numerr).toString());

        }
    }

    /**
     * 如何擴充套件前一個例子,只返回總和能被3整除的數對呢?例如(2, 4)和(3, 3)是可以的。
     */
    public static void methord05() {
        List<Integer> numbers1 = Arrays.asList(1, 2, 3);
        List<Integer> numbers2 = Arrays.asList(3, 4);
        List<Integer[]> collect = numbers1.stream().flatMap(i -> numbers2.stream().filter(j -> (i + j) % 3 == 0).map(j -> new Integer[]{i, j})).collect(Collectors.toList());
        for (Integer[] numerr :
                collect) {
            System.out.println(Arrays.asList(numerr).toString());

        }
    }
}

github 地址哦:https://github.com/wangrui0/jdk1.8