zoukankan      html  css  js  c++  java
  • Java8InAction_Chapter06

      1 import static java.util.Comparator.comparingInt;
      2 import static java.util.stream.Collector.Characteristics.CONCURRENT;
      3 import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH;
      4 import static java.util.stream.Collectors.collectingAndThen;
      5 import static java.util.stream.Collectors.counting;
      6 import static java.util.stream.Collectors.groupingBy;
      7 import static java.util.stream.Collectors.mapping;
      8 import static java.util.stream.Collectors.maxBy;
      9 import static java.util.stream.Collectors.partitioningBy;
     10 import static java.util.stream.Collectors.reducing;
     11 import static java.util.stream.Collectors.summingInt;
     12 import static java.util.stream.Collectors.toSet;
     13 import static lambdasinaction.chap6.Dish.menu;
     14 
     15 import java.util.ArrayList;
     16 import java.util.Collections;
     17 import java.util.EnumSet;
     18 import java.util.HashMap;
     19 import java.util.List;
     20 import java.util.Map;
     21 import java.util.Optional;
     22 import java.util.Set;
     23 import java.util.function.BiConsumer;
     24 import java.util.function.BinaryOperator;
     25 import java.util.function.Function;
     26 import java.util.function.Predicate;
     27 import java.util.function.Supplier;
     28 import java.util.stream.Collector;
     29 import java.util.stream.IntStream;
     30 import java.util.stream.Stream;
     31 
     32 /**
     33  * 在这里编写类的功能描述
     34  *
     35  * @author shangjinyu
     36  * @created 2017/10/5
     37  */
     38 public class Notes {
     39 
     40     /**
     41      * Collectors类的静态工厂方法
     42      * 工厂方法              返回类型                    用于
     43      * toList               List<T>                   把流中所有项目收集到一个List
     44      * 使用示例: List<Dish> dishes = menuStream.collect(toList());
     45      * toSet                Set<T>                    把流中所有项目收集到一个Set,删除重复项
     46      * 使用示例: Set<Dish> dishes = menuStream.collect(toSet());
     47      * toCollection         Collection<T>             把流中所有项目收集到给定的供应源创建的集合
     48      * 使用示例: Collection<Dish> dishes = menuStream.collect(toCollection(), ArrayList::new);
     49      * counting             Long                      计算流中元素的个数
     50      * 使用示例: long howManyDishes = menuStream.collect(counting());
     51      * summingInt           Integer                   对流中项目的一个整数属性求和
     52      * 使用示例: int totalCalories = menuStream.collect(summingInt(Dish::getCalories));
     53      * averagingInt         Double                    计算流中项目Integer属性的平均值
     54      * 使用示例: double avgCalories = menuStream.collect(averagingInt(Dish::getCalories));
     55      * summarizingInt       IntSummaryStatistics      收集关于流中项目Integer属性的统计值,例如最大,最小,总和与平均值
     56      * 使用示例: IntSummaryStatistics menuStatistics = menuStream.collect(summarizingInt(Dish::getCalories));
     57      * joing                String                    连接对流中每个项目调用toString方法所生成的字符串
     58      * 使用示例: String shortMenu = menuStream.map(Dish::getName).collect(joining(", "));
     59      * maxBy                Optional<T>               一个包裹了流中按照给定比较器选出的最大元素的Optional,或如果流为空则为Optional.empty()
     60      * 使用示例: Optional<Dish> fattest = menuStream.collect(maxBy(comparingInt(Dish::getCalories)));
     61      * minBy                Optional<T>               一个包裹了流中按照给定比较器选出的最小元素的Optional,或如果流为空则为Optional.empty()
     62      * 使用示例: Optional<Dish> fattest = menuStream.collect(minBy(comparingInt(Dish::getCalories)));
     63      * reducing             规约操作产生的类型           从一个作为累加器的初始值开始,利用BinaryOperator与流中的元素逐个结合,从而将流规约为单个值
     64      * 使用示例: int totalCalories = menuStream.collect(reducing(0, Dish::getCalories, Integer::sum));
     65      * collectionAndThen    转换函数返回的类型           包裹另一个收集器,对其结果应用转换函数
     66      * 使用示例: int howManyDishes = menuStream.collect(collectingAndThen(toList(), List::size));
     67      * groupingBy           Map<K,List<T>              根据项目的一个属性的值对流中的项目分组,并将属性值作为结果Map的键
     68      * 使用示例: Map<Dish.Type,List<Dish>> dishesByType = menuStream.collect(groupingBy(Dish::getType));
     69      * partitioningBy       Map<Boolean,List<T>        根据对流中每个项目应用谓词的结果来对项目进行分区
     70      * 使用  :Map<Boolean,List<Dish>> vegetarianDishes = menuStream.collect(partitioningBy(Dish::isVegetarian));
     71      */
     72     //返回Colletcors接口
     73     //counting(), maxBy(), summingInt(), averagingInt(), summarizingInt(), joining(), groupingBy
     74 
     75     //reducing()
     76     int totalCalories = menu.stream().collect(reducing(
     77             0, Dish::getCalories, (i, j) -> i + j));
     78 
     79     Optional<Dish> mostCalorieDish =
     80             menu.stream().collect(reducing(
     81                     (d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2));
     82 
     83     public enum CaloricLevel {DIET, NORMAL, FAT};
     84 
     85     Map<CaloricLevel, List<Dish>> dishesByCaloricLevel = menu.stream().collect(groupingBy(dish -> {
     86         if (dish.getCalories() <= 400) return CaloricLevel.DIET;
     87         else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
     88         else return CaloricLevel.FAT;
     89     }));
     90 
     91     //groupingBy()
     92     Map<Dish.Type, Map<CaloricLevel, List<Dish>>> dishesByTypeCaloricLevel = menu.stream().collect(
     93             groupingBy(Dish::getType,
     94                     groupingBy(dish -> {
     95                         if (dish.getCalories() <= 400) return CaloricLevel.DIET;
     96                         else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
     97                         else return CaloricLevel.FAT;
     98                     })
     99             )
    100     );
    101     /**
    102      * {MEAT={DIET=[chicken], NORMAL=[beef], FAT=[pork]},
    103      * FISH={DIET=[prawns], NORMAL=[salmon]},
    104      * OTHER={DIET=[rice, seasonal fruit], NORMAL=[french fries, pizza]}}
    105      */
    106 
    107     Map<Dish.Type, Long> typesCount = menu.stream().collect(
    108             groupingBy(Dish::getType, counting()));
    109     //{MEAT=3, FISH=2, OTHER=4}
    110     //单参数groupingBy(f) 其中f是分类函数,实际是groupingBy(f, toList())的简写法
    111 
    112     Map<Dish.Type, Optional<Dish>> mostCaloricByType1 =
    113             menu.stream()
    114                     .collect(groupingBy(Dish::getType,
    115                             maxBy(comparingInt(Dish::getCalories))));
    116     //{FISH=Optional[salmon], OTHER=Optional[pizza], MEAT=Optional[pork]}
    117 
    118     Map<Dish.Type, Dish> mostCaloricByType2 =
    119             menu.stream().collect(groupingBy(Dish::getType,
    120                     collectingAndThen(maxBy(comparingInt(Dish::getCalories)), Optional::get)));
    121     //{FISH=salmon, OTHER=pizza, MEAT=pork}
    122 
    123     Map<Dish.Type, Integer> totalCaloriesByType =
    124             menu.stream().collect(groupingBy(Dish::getType,
    125                     summingInt(Dish::getCalories)));
    126 
    127     Map<Dish.Type, Set<CaloricLevel>> caloricLevelsByType =
    128             menu.stream().collect(
    129                     groupingBy(Dish::getType, mapping(
    130                             dish -> {
    131                                 if (dish.getCalories() <= 400) return CaloricLevel.DIET;
    132                                 else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
    133                                 else return CaloricLevel.FAT;
    134                             },
    135                             toSet())));   // toCollection(HashSet::new) )));
    136     //{OTHER=[DIET, NORMAL], MEAT=[DIET, NORMAL, FAT], FISH=[DIET, NORMAL]}
    137 
    138     //partitioningBy()
    139     Map<Boolean, List<Dish>> partitionedMenu = menu.stream().collect(partitioningBy(Dish::isVegetarian));
    140     /**
    141      * {false=[pork, beef, chicken, prawns, salmon],
    142      * true=[french fries, rice, season fruit, pizza]}
    143      * <p>
    144      * = List<Dish> vegetarianDishes = menu.stream().filter(Dish::isVegetarian).collect(toList());
    145      */
    146 
    147     Map<Boolean, Map<Dish.Type, List<Dish>>> vegetarianDishesByType = menu.stream().collect(
    148             partitioningBy(Dish::isVegetarian, groupingBy(Dish::getType)));
    149     /**
    150      * {false={FISH=[prawns, salmon], MEAT=[pork, beef, chicken]},
    151      * true={OTHER=[french fries, rice, season fruit, pizza]}}
    152      */
    153 
    154     Map<Boolean, Dish> mostCaloricPartitionedByVegetarian =
    155             menu.stream().collect(partitioningBy(Dish::isVegetarian,
    156                     collectingAndThen(maxBy(comparingInt(Dish::getCalories)), Optional::get)));
    157     //{false=pork, true=pizza}
    158 
    159     //假设你要写个方法,它接受参数int n,并将前n个自数分为质数和非质数
    160     public boolean isPrime(int candidate) {
    161         int candidateRoot = (int) Math.sqrt((double) candidate);
    162         return IntStream.rangeClosed(2, candidateRoot)
    163                 .noneMatch(i -> candidate % i == 0);
    164     }
    165 
    166     public Map<Boolean, List<Integer>> partitionPrimes(int n) {
    167         return IntStream.rangeClosed(2, n).boxed()
    168                 .collect(
    169                         partitioningBy(candidate -> isPrime(candidate)));
    170     }
    171     //自定义收集器
    172     public class ToListCollector<T> implements Collector<T, List<T>, List<T>> {
    173         @Override
    174         public Supplier<List<T>> supplier(){
    175             return ArrayList::new;
    176         }
    177 
    178         @Override
    179         public BiConsumer<List<T>, T> accumulator() {
    180             return List::add;
    181         }
    182 
    183         @Override
    184         public BinaryOperator<List<T>> combiner() {
    185             return (list1, list2) -> {
    186                 list1.addAll(list2);
    187                 return list1;
    188             };
    189         }
    190 
    191         @Override
    192         public Function<List<T>, List<T>> finisher() {
    193             return Function.identity();
    194         }
    195 
    196         @Override
    197         public Set<Characteristics> characteristics() {
    198             return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH, CONCURRENT));
    199         }
    200 
    201     }
    202 
    203     List<Dish> dishes = menu.stream().collect(ArrayList::new, List::add, List::addAll);
    204    
    205 }
     1 public static class PrimeNumbersCollector
     2             implements Collector<Integer, Map<Boolean, List<Integer>>, Map<Boolean, List<Integer>>> {
     3 
     4         @Override
     5         public Supplier<Map<Boolean, List<Integer>>> supplier() {
     6             return () -> new HashMap<Boolean, List<Integer>>() {{
     7                 put(true, new ArrayList<Integer>());
     8                 put(false, new ArrayList<Integer>());
     9             }};
    10         }
    11 
    12         @Override
    13         public BiConsumer<Map<Boolean, List<Integer>>, Integer> accumulator() {
    14             return (Map<Boolean, List<Integer>> acc, Integer candidate) -> {
    15                 acc.get( isPrime( acc.get(true),
    16                         candidate) )
    17                         .add(candidate);
    18             };
    19         }
    20 
    21         @Override
    22         public BinaryOperator<Map<Boolean, List<Integer>>> combiner() {
    23             return (Map<Boolean, List<Integer>> map1, Map<Boolean, List<Integer>> map2) -> {
    24                 map1.get(true).addAll(map2.get(true));
    25                 map1.get(false).addAll(map2.get(false));
    26                 return map1;
    27             };
    28         }
    29 
    30         @Override
    31         public Function<Map<Boolean, List<Integer>>, Map<Boolean, List<Integer>>> finisher() {
    32             return i -> i;
    33         }
    34 
    35         @Override
    36         public Set<Characteristics> characteristics() {
    37             return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH));
    38         }
    39     }
    40 
    41     public Map<Boolean, List<Integer>> partitionPrimesWithInlineCollector(int n) {
    42         return Stream.iterate(2, i -> i + 1).limit(n)
    43                 .collect(
    44                         () -> new HashMap<Boolean, List<Integer>>() {{
    45                             put(true, new ArrayList<Integer>());
    46                             put(false, new ArrayList<Integer>());
    47                         }},
    48                         (acc, candidate) -> {
    49                             acc.get( isPrime(acc.get(true), candidate) )
    50                                     .add(candidate);
    51                         },
    52                         (map1, map2) -> {
    53                             map1.get(true).addAll(map2.get(true));
    54                             map1.get(false).addAll(map2.get(false));
    55                         });
    56     }
    57     public static boolean isPrime(List<Integer> primes, Integer candidate) {
    58         double candidateRoot = Math.sqrt((double) candidate);
    59         //return primes.stream().filter(p -> p < candidateRoot).noneMatch(p -> candidate % p == 0);
    60         return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0);
    61     }
    62 
    63     public static <A> List<A> takeWhile(List<A> list, Predicate<A> p) {
    64         int i = 0;
    65         for (A item : list) {
    66             if (!p.test(item)) {
    67                 return list.subList(0, i);
    68             }
    69             i++;
    70         }
    71         return list;
    72     }
    View Code
  • 相关阅读:
    Struts2之Domain Model(域模型)。
    struts2接收参数的5种方法
    java泛型中特殊符号的含义
    @value取值
    Spring分页实现PageImpl<T>类
    eclipse快捷键整理
    String字符串的截取
    Java调用ASP.NET的webservice故障排除
    根据wsdl文件用soapUi快速创建webService服务(有图有真相)
    @Autowired标签与 @Resource标签 的区别
  • 原文地址:https://www.cnblogs.com/3013218061shang/p/7712862.html
Copyright © 2011-2022 走看看