| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,9 +14,31 @@ | |||
| 14 | 14 | - Dish: 菜肴类,有一个静态属性的菜肴列表 | |
| 15 | 15 | - StreamBasic: 指令式和函数式分别挑选低热量食物名 | |
| 16 | 16 | - StreamOperation: 流操作(中间操作和终端操作) | |
| 17 | + - Laziness: 流操作-中间操作 | ||
| 18 | + - BuildingStreams: 构建流,从值序列,数组,文件来创建流。斐波拉切数列的几种生成方法 | ||
| 19 | + | ||
| 17 | 20 | ||
| 18 | 21 | 使用流 | |
| 19 | 22 | ||
| 20 | 23 | - Filtering: 筛选(谓词筛选:filter;筛选互异的元素:distinct;忽略头几个元素:limit;截短至指定长度:skip) | |
| 21 | 24 | - Mapping: 映射 | |
| 25 | + - Finding: 查找和匹配 | ||
| 26 | + - Reducing: 归约 | ||
| 22 | 27 | - PuttingIntoPractice: 各种流操作的使用示例 | |
| 28 | + - NumericStreams: 数值流(原始类型特化,数值范围) | ||
| 29 | + | ||
| 30 | + 用流收集数据 | ||
| 31 | + | ||
| 32 | + - Summarizing: 归约和汇总 | ||
| 33 | + - Reducing: 收集器的灵活性,以不同的方法执行相同的操作 | ||
| 34 | + - Grouping: 分组 | ||
| 35 | + - Partitioning: 分区 | ||
| 36 | + - GroupingTransactions: 分别使用指令式和函数式进行分组 | ||
| 37 | + - ToListCollector: 自定义 ToListCollector,以及进行自定义收集而不去实现 Collector | ||
| 38 | + - PartitionPrimeNumbers: 将数字按质数和非质数分区;Collector 详解 | ||
| 39 | + - CollectorHarness: 比较收集器的性能 | ||
| 40 | + | ||
| 41 | + | ||
| 42 | + | ||
| 43 | + | ||
| 44 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,23 +9,33 @@ | |||
| 9 | 9 | import java.util.stream.Stream; | |
| 10 | 10 | ||
| 11 | 11 | /** | |
| 12 | + * 构建流:从值序列,数组,文件来创建流 | ||
| 12 | 13 | * 斐波拉切数列的几种生成方法 | |
| 13 | 14 | */ | |
| 14 | 15 | public class BuildingStreams { | |
| 15 | 16 | ||
| 16 | 17 | public static void main(String... args) throws Exception { | |
| 17 | 18 | ||
| 19 | + /** | ||
| 20 | + * 由值创建流 | ||
| 21 | + */ | ||
| 18 | 22 | // Stream.of | |
| 19 | 23 | Stream<String> stream = Stream.of("Java 8", "Lambdas", "In", "Action"); | |
| 20 | 24 | stream.map(String::toUpperCase).forEach(System.out::println); | |
| 21 | 25 | ||
| 22 | 26 | // Stream.empty | |
| 23 | 27 | Stream<String> emptyStream = Stream.empty(); | |
| 24 | 28 | ||
| 29 | + /** | ||
| 30 | + * 由数组创建流 | ||
| 31 | + */ | ||
| 25 | 32 | // Arrays.stream | |
| 26 | 33 | int[] numbers = {2, 3, 5, 7, 11, 13}; | |
| 27 | 34 | System.out.println(Arrays.stream(numbers).sum()); | |
| 28 | 35 | ||
| 36 | + /** | ||
| 37 | + * 由函数生成流:创建无限流 | ||
| 38 | + */ | ||
| 29 | 39 | // Stream.iterate | |
| 30 | 40 | Stream.iterate(0, n -> n + 2) | |
| 31 | 41 | .limit(10) | |
@@ -68,6 +78,9 @@ public int getAsInt() { | |||
| 68 | 78 | }; | |
| 69 | 79 | IntStream.generate(fib).limit(10).forEach(System.out::println); | |
| 70 | 80 | ||
| 81 | + /** | ||
| 82 | + * 由文件生成流 | ||
| 83 | + */ | ||
| 71 | 84 | String path = BuildingStreams.class.getResource("/").getPath() + "/data-building.txt"; | |
| 72 | 85 | long uniqueWords = Files.lines(Paths.get(path), Charset.defaultCharset()) | |
| 73 | 86 | .flatMap(line -> Arrays.stream(line.split(" "))) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,4 @@ | |||
| 1 | - package com.brianway.learning.java8.streamapi; | ||
| 1 | + package com.brianway.learning.java8.streamapi.collect; | ||
| 2 | 2 | ||
| 3 | 3 | import java.util.function.Consumer; | |
| 4 | 4 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,110 @@ | |||
| 1 | + package com.brianway.learning.java8.streamapi.collect; | ||
| 2 | + | ||
| 3 | + import com.brianway.learning.java8.streamapi.Dish; | ||
| 4 | + import static com.brianway.learning.java8.streamapi.Dish.menu; | ||
| 5 | + import static java.util.stream.Collectors.collectingAndThen; | ||
| 6 | + import static java.util.stream.Collectors.counting; | ||
| 7 | + import static java.util.stream.Collectors.groupingBy; | ||
| 8 | + import static java.util.stream.Collectors.mapping; | ||
| 9 | + import static java.util.stream.Collectors.maxBy; | ||
| 10 | + import static java.util.stream.Collectors.summingInt; | ||
| 11 | + import static java.util.stream.Collectors.toSet; | ||
| 12 | + | ||
| 13 | + import java.util.Comparator; | ||
| 14 | + import java.util.List; | ||
| 15 | + import java.util.Map; | ||
| 16 | + import java.util.Optional; | ||
| 17 | + import java.util.Set; | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 分组 | ||
| 21 | + */ | ||
| 22 | + public class Grouping { | ||
| 23 | + | ||
| 24 | + private enum CaloricLevel { | ||
| 25 | + DIET, | ||
| 26 | + NORMAL, | ||
| 27 | + FAT | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public static void main(String... args) { | ||
| 31 | + System.out.println("Dishes grouped by type: " + groupDishesByType()); | ||
| 32 | + System.out.println("Dishes grouped by caloric level: " + groupDishesByCaloricLevel()); | ||
| 33 | + System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel()); | ||
| 34 | + System.out.println("Count dishes in groups: " + countDishesInGroups()); | ||
| 35 | + System.out.println("Most caloric dishes by type: " + mostCaloricDishesByType()); | ||
| 36 | + System.out.println("Most caloric dishes by type: " + mostCaloricDishesByTypeWithoutOprionals()); | ||
| 37 | + System.out.println("Sum calories by type: " + sumCaloriesByType()); | ||
| 38 | + System.out.println("Caloric levels by type: " + caloricLevelsByType()); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + private static CaloricLevel getCaloricLevel(Dish dish) { | ||
| 42 | + if (dish.getCalories() <= 400) { | ||
| 43 | + return CaloricLevel.DIET; | ||
| 44 | + } else if (dish.getCalories() <= 700) { | ||
| 45 | + return CaloricLevel.NORMAL; | ||
| 46 | + } else { | ||
| 47 | + return CaloricLevel.FAT; | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + private static Map<Dish.Type, List<Dish>> groupDishesByType() { | ||
| 52 | + return menu.stream().collect(groupingBy(Dish::getType)); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + private static Map<CaloricLevel, List<Dish>> groupDishesByCaloricLevel() { | ||
| 56 | + return menu.stream().collect( | ||
| 57 | + groupingBy(Grouping::getCaloricLevel)); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 多级分组 | ||
| 62 | + */ | ||
| 63 | + private static Map<Dish.Type, Map<CaloricLevel, List<Dish>>> groupDishedByTypeAndCaloricLevel() { | ||
| 64 | + return menu.stream().collect( | ||
| 65 | + groupingBy(Dish::getType, | ||
| 66 | + groupingBy(Grouping::getCaloricLevel) | ||
| 67 | + ) | ||
| 68 | + ); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * 按子数组收集数据 | ||
| 73 | + */ | ||
| 74 | + private static Map<Dish.Type, Long> countDishesInGroups() { | ||
| 75 | + return menu.stream().collect(groupingBy(Dish::getType, counting())); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + private static Map<Dish.Type, Optional<Dish>> mostCaloricDishesByType() { | ||
| 79 | + return menu.stream().collect( | ||
| 80 | + groupingBy(Dish::getType, | ||
| 81 | + maxBy(Comparator.comparingInt(Dish::getCalories))) | ||
| 82 | + ); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * 按子数组收集数据,把收集器的结果转换为另一种类型 | ||
| 87 | + */ | ||
| 88 | + private static Map<Dish.Type, Dish> mostCaloricDishesByTypeWithoutOprionals() { | ||
| 89 | + return menu.stream().collect( | ||
| 90 | + groupingBy(Dish::getType, | ||
| 91 | + collectingAndThen( | ||
| 92 | + maxBy(Comparator.comparingInt(Dish::getCalories)), | ||
| 93 | + Optional::get))); | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + /** | ||
| 97 | + * 与 groupingBy 联合使用的其他收集器例子 | ||
| 98 | + */ | ||
| 99 | + private static Map<Dish.Type, Integer> sumCaloriesByType() { | ||
| 100 | + return menu.stream().collect(groupingBy(Dish::getType, | ||
| 101 | + summingInt(Dish::getCalories))); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + private static Map<Dish.Type, Set<CaloricLevel>> caloricLevelsByType() { | ||
| 105 | + return menu.stream().collect( | ||
| 106 | + groupingBy(Dish::getType, mapping( | ||
| 107 | + Grouping::getCaloricLevel, | ||
| 108 | + toSet()))); | ||
| 109 | + } | ||
| 110 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,4 @@ | |||
| 1 | - package com.brianway.learning.java8.streamapi; | ||
| 1 | + package com.brianway.learning.java8.streamapi.collect; | ||
| 2 | 2 | ||
| 3 | 3 | import static java.util.stream.Collectors.groupingBy; | |
| 4 | 4 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,4 @@ | |||
| 1 | - package com.brianway.learning.java8.streamapi; | ||
| 1 | + package com.brianway.learning.java8.streamapi.collect; | ||
| 2 | 2 | ||
| 3 | 3 | import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH; | |
| 4 | 4 | import static java.util.stream.Collectors.partitioningBy; | |
@@ -39,6 +39,9 @@ public static Map<Boolean, List<Integer>> partitionPrimes(int n) { | |||
| 39 | 39 | .collect(partitioningBy(PartitionPrimeNumbers::isPrime)); | |
| 40 | 40 | } | |
| 41 | 41 | ||
| 42 | + /** | ||
| 43 | + * 判断一个数是不是质数 | ||
| 44 | + */ | ||
| 42 | 45 | public static boolean isPrime(int candidate) { | |
| 43 | 46 | return IntStream.rangeClosed(2, candidate - 1) | |
| 44 | 47 | .limit((long) Math.floor(Math.sqrt((double) candidate)) - 1) | |
@@ -49,12 +52,22 @@ public static Map<Boolean, List<Integer>> partitionPrimesWithCustomCollector(int | |||
| 49 | 52 | return IntStream.rangeClosed(2, n).boxed().collect(new PrimeNumbersCollector()); | |
| 50 | 53 | } | |
| 51 | 54 | ||
| 55 | + /** | ||
| 56 | + * 仅用质数作除数 | ||
| 57 | + * | ||
| 58 | + * @param primes 部分结果 | ||
| 59 | + * @param candidate 要判断的数 | ||
| 60 | + * @return | ||
| 61 | + */ | ||
| 52 | 62 | public static boolean isPrime(List<Integer> primes, Integer candidate) { | |
| 53 | 63 | double candidateRoot = Math.sqrt((double) candidate); | |
| 54 | 64 | //return primes.stream().filter(p -> p < candidateRoot).noneMatch(p -> candidate % p == 0); | |
| 55 | 65 | return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0); | |
| 56 | 66 | } | |
| 57 | 67 | ||
| 68 | + /** | ||
| 69 | + * 返回元素满足谓词的最长前缀 | ||
| 70 | + */ | ||
| 58 | 71 | public static <A> List<A> takeWhile(List<A> list, Predicate<A> p) { | |
| 59 | 72 | int i = 0; | |
| 60 | 73 | for (A item : list) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,42 @@ | |||
| 1 | + package com.brianway.learning.java8.streamapi.collect; | ||
| 2 | + | ||
| 3 | + import com.brianway.learning.java8.streamapi.Dish; | ||
| 4 | + import static com.brianway.learning.java8.streamapi.Dish.menu; | ||
| 5 | + import static java.util.Comparator.comparingInt; | ||
| 6 | + import static java.util.stream.Collectors.collectingAndThen; | ||
| 7 | + import static java.util.stream.Collectors.groupingBy; | ||
| 8 | + import static java.util.stream.Collectors.maxBy; | ||
| 9 | + import static java.util.stream.Collectors.partitioningBy; | ||
| 10 | + | ||
| 11 | + import java.util.List; | ||
| 12 | + import java.util.Map; | ||
| 13 | + import java.util.Optional; | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * 分区 | ||
| 17 | + */ | ||
| 18 | + public class Partitioning { | ||
| 19 | + | ||
| 20 | + public static void main(String... args) { | ||
| 21 | + System.out.println("Dishes partitioned by vegetarian: " + partitionByVegeterian()); | ||
| 22 | + System.out.println("Vegetarian Dishes by type: " + vegetarianDishesByType()); | ||
| 23 | + System.out.println("Most caloric dishes by vegetarian: " + mostCaloricPartitionedByVegetarian()); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + private static Map<Boolean, List<Dish>> partitionByVegeterian() { | ||
| 27 | + return menu.stream().collect(partitioningBy(Dish::isVegetarian)); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + private static Map<Boolean, Map<Dish.Type, List<Dish>>> vegetarianDishesByType() { | ||
| 31 | + return menu.stream().collect(partitioningBy(Dish::isVegetarian, groupingBy(Dish::getType))); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + private static Object mostCaloricPartitionedByVegetarian() { | ||
| 35 | + return menu.stream().collect( | ||
| 36 | + partitioningBy(Dish::isVegetarian, | ||
| 37 | + collectingAndThen( | ||
| 38 | + maxBy(comparingInt(Dish::getCalories)), | ||
| 39 | + Optional::get))); | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,12 @@ | |||
| 1 | - package com.brianway.learning.java8.streamapi; | ||
| 1 | + package com.brianway.learning.java8.streamapi.collect; | ||
| 2 | 2 | ||
| 3 | + import com.brianway.learning.java8.streamapi.Dish; | ||
| 3 | 4 | import static com.brianway.learning.java8.streamapi.Dish.menu; | |
| 4 | 5 | import static java.util.stream.Collectors.reducing; | |
| 5 | 6 | ||
| 7 | + /** | ||
| 8 | + * 收集器的灵活性,以不同的方法执行相同的操作 | ||
| 9 | + */ | ||
| 6 | 10 | public class Reducing { | |
| 7 | 11 | ||
| 8 | 12 | public static void main(String... args) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,86 @@ | |||
| 1 | + package com.brianway.learning.java8.streamapi.collect; | ||
| 2 | + | ||
| 3 | + import com.brianway.learning.java8.streamapi.Dish; | ||
| 4 | + import static com.brianway.learning.java8.streamapi.Dish.menu; | ||
| 5 | + import static java.util.stream.Collectors.averagingInt; | ||
| 6 | + import static java.util.stream.Collectors.counting; | ||
| 7 | + import static java.util.stream.Collectors.joining; | ||
| 8 | + import static java.util.stream.Collectors.reducing; | ||
| 9 | + import static java.util.stream.Collectors.summarizingInt; | ||
| 10 | + import static java.util.stream.Collectors.summingInt; | ||
| 11 | + | ||
| 12 | + import java.util.Comparator; | ||
| 13 | + import java.util.IntSummaryStatistics; | ||
| 14 | + import java.util.function.BinaryOperator; | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * 归约和汇总 | ||
| 18 | + */ | ||
| 19 | + public class Summarizing { | ||
| 20 | + | ||
| 21 | + public static void main(String... args) { | ||
| 22 | + System.out.println("Nr. of dishes: " + howManyDishes()); | ||
| 23 | + System.out.println("The most caloric dish is: " + findMostCaloricDish()); | ||
| 24 | + System.out.println("The most caloric dish is: " + findMostCaloricDishUsingComparator()); | ||
| 25 | + System.out.println("Total calories in menu: " + calculateTotalCalories()); | ||
| 26 | + System.out.println("Average calories in menu: " + calculateAverageCalories()); | ||
| 27 | + System.out.println("Menu statistics: " + calculateMenuStatistics()); | ||
| 28 | + System.out.println("Short menu: " + getShortMenu()); | ||
| 29 | + System.out.println("Short menu comma separated: " + getShortMenuCommaSeparated()); | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * 统计个数 | ||
| 34 | + */ | ||
| 35 | + private static long howManyDishes() { | ||
| 36 | + return menu.stream().collect(counting()); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * 查找流中最大值 | ||
| 41 | + */ | ||
| 42 | + private static Dish findMostCaloricDish() { | ||
| 43 | + return menu.stream().collect(reducing((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2)).get(); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 查找流中最大值 | ||
| 48 | + */ | ||
| 49 | + private static Dish findMostCaloricDishUsingComparator() { | ||
| 50 | + Comparator<Dish> dishCaloriesComparator = Comparator.comparingInt(Dish::getCalories); | ||
| 51 | + BinaryOperator<Dish> moreCaloricOf = BinaryOperator.maxBy(dishCaloriesComparator); | ||
| 52 | + return menu.stream().collect(reducing(moreCaloricOf)).get(); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * 汇总-求和 | ||
| 57 | + */ | ||
| 58 | + private static int calculateTotalCalories() { | ||
| 59 | + return menu.stream().collect(summingInt(Dish::getCalories)); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * 汇总-求平均数 | ||
| 64 | + */ | ||
| 65 | + private static Double calculateAverageCalories() { | ||
| 66 | + return menu.stream().collect(averagingInt(Dish::getCalories)); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + /** | ||
| 70 | + * 汇总-统计值 | ||
| 71 | + */ | ||
| 72 | + private static IntSummaryStatistics calculateMenuStatistics() { | ||
| 73 | + return menu.stream().collect(summarizingInt(Dish::getCalories)); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * 连接字符串 | ||
| 78 | + */ | ||
| 79 | + private static String getShortMenu() { | ||
| 80 | + return menu.stream().map(Dish::getName).collect(joining()); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + private static String getShortMenuCommaSeparated() { | ||
| 84 | + return menu.stream().map(Dish::getName).collect(joining(", ")); | ||
| 85 | + } | ||
| 86 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments