第2篇 stream -- 對映(map or flatmap)
阿新 • • 發佈:2018-11-08
/** * 對映: * 一個非常常見的資料處理套路就是從某些物件中選擇資訊。比如在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