zoukankan      html  css  js  c++  java
  • Java8 Stream 之groupingBy 分组,计数和排序

    例1:

      1 public class GroupBy {
      2 
      3     List<Employee> employees = new ArrayList<>();
      4 
      5     /**
      6      * 数据初始化
      7      */
      8     public void init() {
      9         List<String> citys = Arrays.asList("湖南", "湖北", "四川", "广东 ");
     10         for (int i = 0; i < 10; i++) {
     11             Random random = new Random();
     12             Integer index = random.nextInt(4);
     13             Employee employee = new Employee(citys.get(index), "姓名" + i, (random.nextInt(4) * 10 - random.nextInt(4)),
     14                     (random.nextInt(4) * 1000 - random.nextInt(4)));
     15             employees.add(employee);
     16         }
     17     }
     18 
     19     /**
     20      * 使用java8 stream groupingBy操作,按城市分组list
     21      */
     22     public void groupingByCity() {
     23         Map<String, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity));
     24 
     25         map.forEach((k, v) -> System.out.println(k + " = " + v));
     26         //四川 = [GroupBy.Employee(city=四川, name=姓名1, age=30, amount=999), GroupBy.Employee(city=四川, name=姓名2, age=8, amount=2000), GroupBy.Employee(city=四川, name=姓名3, age=30, amount=2997)]
     27         //湖南 = [GroupBy.Employee(city=湖南, name=姓名7, age=30, amount=-3), GroupBy.Employee(city=湖南, name=姓名8, age=19, amount=1998)]
     28         //湖北 = [GroupBy.Employee(city=湖北, name=姓名4, age=29, amount=-2), GroupBy.Employee(city=湖北, name=姓名5, age=10, amount=1997)]
     29         //广东  = [GroupBy.Employee(city=广东 , name=姓名0, age=28, amount=1998), GroupBy.Employee(city=广东 , name=姓名6, age=29, amount=1998), GroupBy.Employee(city=广东 , name=姓名9, age=7, amount=1000)]
     30     }
     31 
     32     /**
     33      * 使用java8 stream groupingBy操作,按城市分组list统计count
     34      */
     35     public void groupingByCount() {
     36         Map<String, Long> map = employees.stream()
     37                 .collect(Collectors.groupingBy(Employee::getCity, Collectors.counting()));
     38 
     39         map.forEach((k, v) -> System.out.println(k + " = " + v));
     40         //四川 = 1
     41         //湖北 = 3
     42         //湖南 = 4
     43         //广东  = 2
     44     }
     45 
     46     /**
     47      * 使用java8 stream groupingBy操作,按城市分组list并计算分组年龄平均值
     48      */
     49     public void groupingByAverage() {
     50         Map<String, Double> map = employees.stream()
     51                 .collect(Collectors.groupingBy(Employee::getCity, Collectors.averagingInt(Employee::getAge)));
     52 
     53         map.forEach((k, v) -> System.out.println(k + " = " + v));
     54         //四川 = 15.0
     55         //湖北 = 21.25
     56         //湖南 = 18.333333333333332
     57         //广东  = 9.0
     58     }
     59 
     60     /**
     61      * 使用java8 stream groupingBy操作,按城市分组list并计算分组销售总值
     62      */
     63     public void groupingBySum() {
     64         Map<String, Long> map = employees.stream()
     65                 .collect(Collectors.groupingBy(Employee::getCity, Collectors.summingLong(Employee::getAmount)));
     66 
     67         map.forEach((k, v) -> System.out.println(k + " = " + v));
     68         //四川 = 3995
     69         //湖北 = 2995
     70         //湖南 = 999
     71         //广东  = 8994
     72 
     73         // 对Map按照分组销售总值逆序排序
     74         Map<String, Long> sortedMap = new LinkedHashMap<>();
     75         map.entrySet().stream().sorted(Map.Entry.<String, Long> comparingByValue().reversed())
     76                 .forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue()));
     77 
     78         sortedMap.forEach((k, v) -> System.out.println(k + " = " + v));
     79         //广东  = 8994
     80         //四川 = 3995
     81         //湖北 = 2995
     82         //湖南 = 999
     83     }
     84 
     85 
     86     /**
     87      * 使用java8 stream groupingBy操作,按城市分组list并通过join操作连接分组list中的对象的name 属性使用逗号分隔
     88      */
     89     public void groupingByString() {
     90         Map<String, String> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity,
     91                 Collectors.mapping(Employee::getName, Collectors.joining(", ", "Names: [", "]"))));
     92 
     93         map.forEach((k, v) -> System.out.println(k + " = " + v));
     94         //四川 = Names: [姓名8]
     95         //湖南 = Names: [姓名1, 姓名2, 姓名7]
     96         //湖北 = Names: [姓名0, 姓名3, 姓名6, 姓名9]
     97         //广东  = Names: [姓名4, 姓名5]
     98     }
     99 
    100     /**
    101      * 使用java8 stream groupingBy操作,按城市分组list,将List转化为name的List
    102      */
    103     public void groupingByList() {
    104         Map<String, List<String>> map = employees.stream().collect(
    105                 Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toList())));
    106 
    107         map.forEach((k, v) -> {
    108             System.out.println(k + " = " + v);
    109             v.forEach(item -> System.out.println("item = " + item));
    110         });
    111         //四川 = [姓名6]
    112         //item = 姓名6
    113         //湖北 = [姓名2, 姓名5, 姓名7]
    114         //item = 姓名2
    115         //item = 姓名5
    116         //item = 姓名7
    117         //湖南 = [姓名0, 姓名1, 姓名3, 姓名4]
    118         //item = 姓名0
    119         //item = 姓名1
    120         //item = 姓名3
    121         //item = 姓名4
    122         //广东  = [姓名8, 姓名9]
    123         //item = 姓名8
    124         //item = 姓名9
    125     }
    126 
    127     /**
    128      * 使用java8 stream groupingBy操作,按城市分组list,将List转化为name的Set
    129      */
    130     public void groupingBySet() {
    131         Map<String, Set<String>> map = employees.stream().collect(
    132                 Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toSet())));
    133 
    134         map.forEach((k, v) -> {
    135             System.out.println(k + " = " + v);
    136             v.forEach(item -> System.out.println("item = " + item));
    137         });
    138     }
    139 
    140     /**
    141      * 使用java8 stream groupingBy操作,通过Object对象的成员分组List
    142      */
    143     public void groupingByObject() {
    144         Map<Manage, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(item -> new Manage(item.getName())));
    145 
    146         map.forEach((k, v) -> System.out.println(k + " = " + v));
    147         //GroupBy.Manage(name=姓名9) = [GroupBy.Employee(city=广东 , name=姓名9, age=19, amount=2998)]
    148         //GroupBy.Manage(name=姓名8) = [GroupBy.Employee(city=四川, name=姓名8, age=-2, amount=3000)]
    149         //GroupBy.Manage(name=姓名7) = [GroupBy.Employee(city=广东 , name=姓名7, age=8, amount=2999)]
    150         //GroupBy.Manage(name=姓名2) = [GroupBy.Employee(city=广东 , name=姓名2, age=10, amount=0)]
    151         //GroupBy.Manage(name=姓名1) = [GroupBy.Employee(city=四川, name=姓名1, age=-1, amount=1998)]
    152         //GroupBy.Manage(name=姓名0) = [GroupBy.Employee(city=湖南, name=姓名0, age=17, amount=1997)]
    153         //GroupBy.Manage(name=姓名6) = [GroupBy.Employee(city=湖北, name=姓名6, age=9, amount=1000)]
    154         //GroupBy.Manage(name=姓名5) = [GroupBy.Employee(city=湖北, name=姓名5, age=8, amount=1000)]
    155         //GroupBy.Manage(name=姓名4) = [GroupBy.Employee(city=湖南, name=姓名4, age=-3, amount=3000)]
    156         //GroupBy.Manage(name=姓名3) = [GroupBy.Employee(city=广东 , name=姓名3, age=17, amount=1999)]
    157     }
    158 
    159     /**
    160      * 使用java8 stream groupingBy操作, 基于city 和name 实现多次分组
    161      */
    162     public void groupingBys() {
    163         Map<String, Map<String, List<Employee>>> map = employees.stream()
    164                 .collect(Collectors.groupingBy(Employee::getCity, Collectors.groupingBy(Employee::getName)));
    165 
    166         map.forEach((k, v) -> {
    167             System.out.println(k + " = " + v);
    168             v.forEach((i, j) -> System.out.println(i + " = " + j));
    169         });
    170         //四川 = {姓名6=[GroupBy.Employee(city=四川, name=姓名6, age=-3, amount=997)]}
    171         //姓名6 = [GroupBy.Employee(city=四川, name=姓名6, age=-3, amount=997)]
    172 
    173         //湖南 = {姓名5=[GroupBy.Employee(city=湖南, name=姓名5, age=-2, amount=0)]}
    174         //姓名5 = [GroupBy.Employee(city=湖南, name=姓名5, age=-2, amount=0)]
    175 
    176         //湖北 = {姓名4=[GroupBy.Employee(city=湖北, name=姓名4, age=10, amount=-2)], 姓名3=[GroupBy.Employee(city=湖北, name=姓名3, age=8, amount=997)], 姓名2=[GroupBy.Employee(city=湖北, name=姓名2, age=8, amount=999)], 姓名9=[GroupBy.Employee(city=湖北, name=姓名9, age=29, amount=-2)], 姓名1=[GroupBy.Employee(city=湖北, name=姓名1, age=30, amount=2000)]}
    177         //姓名4 = [GroupBy.Employee(city=湖北, name=姓名4, age=10, amount=-2)]
    178         //姓名3 = [GroupBy.Employee(city=湖北, name=姓名3, age=8, amount=997)]
    179         //姓名2 = [GroupBy.Employee(city=湖北, name=姓名2, age=8, amount=999)]
    180         //姓名9 = [GroupBy.Employee(city=湖北, name=姓名9, age=29, amount=-2)]
    181         //姓名1 = [GroupBy.Employee(city=湖北, name=姓名1, age=30, amount=2000)]
    182 
    183         //广东  = {姓名8=[GroupBy.Employee(city=广东 , name=姓名8, age=-1, amount=-3)], 姓名7=[GroupBy.Employee(city=广东 , name=姓名7, age=29, amount=998)], 姓名0=[GroupBy.Employee(city=广东 , name=姓名0, age=0, amount=2999)]}
    184         //姓名8 = [GroupBy.Employee(city=广东 , name=姓名8, age=-1, amount=-3)]
    185         //姓名7 = [GroupBy.Employee(city=广东 , name=姓名7, age=29, amount=998)]
    186         //姓名0 = [GroupBy.Employee(city=广东 , name=姓名0, age=0, amount=2999)]
    187     }
    188 
    189     /**
    190      * 使用java8 stream groupingBy操作, 基于Distinct 去重数据
    191      */
    192     public void groupingByDistinct() {
    193         List<Employee> list = employees.stream().filter(distinctByKey(Employee :: getCity))
    194                 .collect(Collectors.toList());
    195 
    196         list.forEach(item-> System.out.println("city = " + item.getCity()));
    197         //city = 湖南
    198         //city = 湖北
    199         //city = 四川
    200         //city = 广东
    201     }
    202 
    203     /**
    204      * 自定义重复key 规则
    205      */
    206     private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    207         Set<Object> seen = ConcurrentHashMap.newKeySet();
    208         return t -> seen.add(keyExtractor.apply(t));
    209     }
    210 
    211     public static void main(String[] args) {
    212         GroupBy instance = new GroupBy();
    213         instance.init();
    214         instance.groupingByCity();
    215         instance.groupingByCount();
    216         instance.groupingByAverage();
    217         instance.groupingBySum();
    218         instance.groupingByString();
    219         instance.groupingByList();
    220         instance.groupingBySet();
    221         instance.groupingByObject();
    222         instance.groupingBys();
    223         instance.groupingByDistinct();
    224 
    225     }
    226 
    227     @Data
    228     @NoArgsConstructor
    229     @AllArgsConstructor
    230     class Employee {
    231         private String city;
    232         private String name;
    233         private Integer age;
    234         private Integer amount;
    235 
    236     }
    237 
    238     @Data
    239     @NoArgsConstructor
    240     @AllArgsConstructor
    241     class Manage {
    242         private String name;
    243 
    244     }
    245 
    246 }

    例2:

     1 /**
     2 * 分组List并显示其总数
     3 */
     4 @Test  
     5 void test1(){
     6 //3 apple, 2 banana, others 1
     7     List items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya");
     8     Map<String, Long> collect = items.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); 
     9     System.out.println(collect); //{papaya=1, orange=1, banana=2, apple=3}
    10 }
    11 
    12 /**
    13  * 添加排序
    14  */
    15 @Test
    16 void test2(){
    17     List<String> items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya");
    18     Map<String, Long> map = items.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    19     Map<String, Long> finalMap = new LinkedHashMap<>();
    20     map.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed()).forEachOrdered(e->finalMap.put(e.getKey(),e.getValue()));
    21 
    22     System.out.println(finalMap); //{apple=3, banana=2, papaya=1, orange=1}
    23 }
    24 
    25 /**
    26  * 按姓名+ 数字或数量组合
    27  */
    28 @Test
    29 void test3(){
    30     //3 apple, 2 banana, others 1
    31     List<Item> items = Arrays.asList(
    32             new Item("apple", 10, new BigDecimal("9.99")),
    33             new Item("banana", 20, new BigDecimal("19.99")),
    34             new Item("orange", 10, new BigDecimal("29.99")),
    35             new Item("watermelon", 10, new BigDecimal("29.99")),
    36             new Item("papaya", 20, new BigDecimal("9.99")),
    37             new Item("apple", 10, new BigDecimal("9.99")),
    38             new Item("banana", 10, new BigDecimal("19.99")),
    39             new Item("apple", 20, new BigDecimal("9.99"))
    40     );
    41     Map<String, Long> counting = items.stream().collect(Collectors.groupingBy(Item::getName, Collectors.counting()));
    42     System.out.println(counting); //{papaya=1, orange=1, banana=2, apple=3, watermelon=1}
    43 
    44     Map<String, Integer> map = items.stream().collect(Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getNumber)));
    45     System.out.println(map); //{papaya=20, orange=10, banana=30, apple=40, watermelon=10}
    46 }
    47 
    48 /**
    49  * 按价格分组
    50  */
    51 @Test
    52 void test4(){
    53     //3 apple, 2 banana, others 1
    54     List<Item> items = Arrays.asList(
    55             new Item("apple", 10, new BigDecimal("9.99")),
    56             new Item("banana", 20, new BigDecimal("19.99")),
    57             new Item("orange", 10, new BigDecimal("29.99")),
    58             new Item("watermelon", 10, new BigDecimal("29.99")),
    59             new Item("papaya", 20, new BigDecimal("9.99")),
    60             new Item("apple", 10, new BigDecimal("9.99")),
    61             new Item("banana", 10, new BigDecimal("19.99")),
    62             new Item("apple", 20, new BigDecimal("9.99"))
    63     );
    64     Map<BigDecimal, List<Item>> decimalListMap = items.stream().collect(Collectors.groupingBy(Item::getPrice));
    65     System.out.println(decimalListMap);
    66     //{19.99=[Item(name=banana, number=20, price=19.99),
    67     //        Item(name=banana, number=10, price=19.99)],
    68     // 29.99=[Item(name=orange, number=10, price=29.99),
    69     //        Item(name=watermelon, number=10, price=29.99)],
    70     // 9.99=[Item(name=apple, number=10, price=9.99),
    71     //       Item(name=papaya, number=20, price=9.99),
    72     //       Item(name=apple, number=10, price=9.99),
    73     //       Item(name=apple, number=20, price=9.99)]}
    74 
    75     Map<BigDecimal, Set<String>> setMap = items.stream().collect(Collectors.groupingBy(Item::getPrice, Collectors.mapping(Item::getName, Collectors.toSet())));
    76     System.out.println(setMap);
    77     //{19.99=[banana],
    78     // 29.99=[orange, watermelon],
    79     // 9.99=[papaya, apple]}
    80 }
    作者:donleo123
    本文如对您有帮助,还请多推荐下此文,如有错误欢迎指正,相互学习,共同进步。
  • 相关阅读:
    jQuery(Ajax)
    博文相关接口
    登录接口设计和实现
    CSS-层叠样式表
    Google Kaptcha 生成图形验证码
    IDEA中如何修改生成javadoc里默认的author
    maven项目resources文件在target找不到
    IDEA 获取 resources 下的文件
    免安装版 mysql5.7.zip 的配置记录
    从前端模块化 到 webpack 再到使用 vue文件
  • 原文地址:https://www.cnblogs.com/donleo123/p/15621094.html
Copyright © 2011-2022 走看看