zoukankan      html  css  js  c++  java
  • JDK1.8新特性Stream和Collectors19个常用示例总结

    JDK1.8新特性Stream和Collectors19个常用示例总结

     

    关于Stream和Collectors的用法,这应该是总结的最全的文章了,大家可以收藏一下。

    一:简介

    java.util.Stream 表示能应用在一组元素上一次执行的操作序列。Stream 操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,这样就可以将多个操作依次串起来。Stream 的创建需要指定一个数据源,比如 java.util.Collection的子类,List或者Set, Map不支持。Stream的操作可以串行stream()执行或者并行parallelStream()执行。

    二:示例

    forEach 循环

    @Test
    public void forEach(){
     // 你不鸟我,我也不鸟你
     List<String> list = Arrays.asList("you", "don't", "bird", "me", ",", 
                                         "I", "don't", "bird", "you");
     // 方式一:JDK1.8之前的循环方式
     for (String item: list) {
     System.out.println(item);
     }
     // 方式二:使用Stream的forEach方法
     // void forEach(Consumer<? super T> action)
     list.stream().forEach(item -> System.out.println(item));
     // 方式三:方式二的简化方式
     // 由于方法引用也属于函数式接口,所以方式二Lambda表达式也可以使用方法引用来代替
     // 此种方式就是方式一、方式二的简写形式
     list.stream().forEach(System.out::println);
    }

    filter 过滤

    public class User {
     private Long id;
     private String phone;
     private Integer age;
        public User(){}
     public User(Long id, String username, Integer age) {
     this.id = id;
     this.username = username;
     this.age = age;
     }
        // Getter & Setter & toString
    }
    @Test
    public void filter(){
        List<User> users = Arrays.asList(
     new User(1L, "mengday", 28),
     new User(2L, "guoguo", 18),
     new User(3L, "liangliang", 17)
     );
     // Stream<T> filter(Predicate<? super T> predicate);
     users.stream().filter(user -> user.getAge() > 18).forEach(System.out::println);
    }

    map 映射

    @Test
    public void map(){
     List<String> list = Arrays.asList("how", "are", "you", "how", "old", "are", "you", "?");
     // <R> Stream<R> map(Function<? super T, ? extends R> mapper);
     list.stream().map(item -> item.toUpperCase()).forEach(System.out::println);
    }

    flatMap

    @Test
    public void flatMap(){
     List<Integer> a = Arrays.asList(1, 2, 3);
     List<Integer> b = Arrays.asList(4, 5, 6);
     // <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
     List<List<Integer>> collect = Stream.of(a, b).collect(Collectors.toList());
     // [[1, 2, 3], [4, 5, 6]] 
     System.out.println(collect);
     // 将多个集合中的元素合并成一个集合
     List<Integer> mergeList = Stream.of(a, b).flatMap(list -> list.stream()).collect(Collectors.toList());
     // [1, 2, 3, 4, 5, 6]
     System.out.println(mergeList);
     // 通过Builder模式来构建
     Stream<Object> stream = Stream.builder().add("hello").add("hi").add("byebye").build();
    }

    sorted 排序

    @Test
    public void sort(){
     List<String> list = Arrays.asList("c", "e", "a", "d", "b");
     // Stream<T> sorted(Comparator<? super T> comparator);
     // int compare(T o1, T o2);
     list.stream().sorted((s1, s2) -> s1.compareTo(s2)).forEach(System.out::println);
    }

    distinct 去重复

    @Test
    public void distinct(){
     // 知之为知之,不知为不知
     Stream<String> stream = Stream.of("know", "is", "know", "noknow", "is", "noknow");
     stream.distinct().forEach(System.out::println); // know is noknow
    }

    count 总数量

    @Test
    public void count(){
     Stream<String> stream = Stream.of("know", "is", "know", "noknow", "is", "noknow");
     long count = stream.count();
     System.out.println(count);
    }

    min、max

    @Test
    public void min(){
     List<String> list = Arrays.asList("1", "2", "3", "4", "5");
     // Optional<T> min(Comparator<? super T> comparator);
     Optional<String> optional = list.stream().min((a, b) -> a.compareTo(b));
     String value = optional.get();
     System.out.println(value);
    }

    skip、limit

    @Test
    public void skip(){
     List<String> list = Arrays.asList("a", "b", "c", "d", "e");
     // Stream<T> skip(long n)
     list.stream().skip(2).forEach(System.out::println); // c、d、e
    }
    @Test
    public void limit(){
     List<String> list = Arrays.asList("a", "b", "c", "d", "e");
     list.stream().skip(2).limit(2).forEach(System.out::println); // c、d
    }

    collect

    @Test
    public void collect(){
     List<String> list = Arrays.asList("a", "b", "c", "d", "e");
     // Stream -> Collection
     List<String> collect = list.stream().collect(Collectors.toList());
     // Stream -> Object[]
     Object[] objects = list.stream().toArray();
    }

    concat

    @Test
    public void concat(){
     List<String> list = Arrays.asList("a", "b");
     List<String> list2 = Arrays.asList("c", "d");
     Stream<String> concatStream = Stream.concat(list.stream(), list2.stream());
     concatStream.forEach(System.out::println);
    }

    anyMatch、allMatch

    @Test
    public void match(){
     // 你给我站住
     List<String> list = Arrays.asList("you", "give", "me", "stop");
     // boolean anyMatch(Predicate<? super T> predicate);
     // parallelStream可以并行计算,速度比stream更快
     boolean result = list.parallelStream().anyMatch(item -> item.equals("me"));
     System.out.println(result);
    }
    /**
    * anyMatch伪代码
     * 如果集合中有一个元素满足条件就返回true
     * @return
     */
    public boolean anyMatch() {
     List<String> list = Arrays.asList("you", "give", "me", "stop");
     for (String item : list) {
     if (item.equals("me")) {
     return true;
     }
     }
     return false;
    }

    reduce 归纳

    @Test
    public void reduce(){
     Stream<String> stream = Stream.of("you", "give", "me", "stop");
     // Optional<T> reduce(BinaryOperator<T> accumulator);
     Optional<String> optional = stream.reduce((before, after) -> before + "," + after);
     optional.ifPresent(System.out::println); // you,give,me,stop
    }

    findFirst、findAny

    @Test
    public void findFirst(){
     Stream<String> stream = Stream.of("you", "give", "me", "stop");
     String value = stream.findFirst().get();
     System.out.println(value);
    }
    @Test
    public void findAny(){
     Stream<String> stream = Stream.of("you", "give", "me", "stop");
     String value2 = stream.findAny().get();
     System.out.println(value2);
    }

    流转换成集合

    @Test
    public void testToCollection(){
     List<Integer> list = Arrays.asList(1, 2, 3);
     // [10, 20, 30]
     List<Integer> collect = list.stream().map(i -> i * 10).collect(Collectors.toList());
     
     // [20, 10, 30]
     Set<Integer> collect1 = list.stream().map(i -> i * 10).collect(Collectors.toSet());
     
     // {key1=value:10, key2=value:20, key3=value:30}
     Map<String, String> collect2 = list.stream().map(i -> i * 10).collect(Collectors.toMap(key -> "key" + key/10, value -> "value:" + value));
     
     // [1, 3, 4]
     TreeSet<Integer> collect3= Stream.of(1, 3, 4).collect(Collectors.toCollection(TreeSet::new));
    }
    @Data
    @ToString
    @AllArgsConstructor
    @RequiredArgsConstructor
    public class User {
     private Long id;
     private String username;
    }
    @Test
    public void testToMap() {
        List<User> userList = Arrays.asList(
         new User(1L, "mengday"),
         new User(2L, "mengdee"),
         new User(3L, "mengdy")
        );
        
        // toMap 可用于将List转为Map,便于通过key快速查找到某个value
        Map<Long, User> userIdAndModelMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        User user = userIdAndModelMap.get(1L);
        // User(id=1, username=mengday)
        System.out.println(user);
        
        Map<Long, String> userIdAndUsernameMap = userList.stream().collect(Collectors.toMap(User::getId, User::getUsername));
        String username = userIdAndUsernameMap.get(1L);
        // mengday
        System.out.println(username);
    }

    集合元素拼接

    @Test
    public void testJoining(){
     // a,b,c
     List<String> list2 = Arrays.asList("a", "b", "c");
     String result = list2.stream().collect(Collectors.joining(","));
     // Collectors.joining(",")的结果是:a,b,c 然后再将结果 x + "d"操作, 最终返回a,b,cd
     String str= Stream.of("a", "b", "c").collect(Collectors.collectingAndThen(Collectors.joining(","), x -> x + "d"));
    }

    元素聚合

    @Test
    public void test(){
     // 求最值 3
     List<Integer> list = Arrays.asList(1, 2, 3);
     Integer maxValue = list.stream().collect(Collectors.collectingAndThen(Collectors.maxBy((a, b) -> a - b), Optional::get));
     // 最小值 1
     Integer minValue = list.stream().collect(Collectors.collectingAndThen(Collectors.minBy((a, b) -> a - b), Optional::get));
     // 求和 6
     Integer sumValue = list.stream().collect(Collectors.summingInt(item -> item));
     // 平均值 2.0
     Double avg = list.stream().collect(Collectors.averagingDouble(x -> x));
    }
    @Test
    public void test(){
        // 映射:先对集合中的元素进行映射,然后再对映射的结果使用Collectors操作
     // A,B,C
     Stream.of("a", "b", "c").collect(Collectors.mapping(x -> x.toUpperCase(), Collectors.joining(",")));
    }

    分组

    public class User {
     private Long id;
     private String username;
     private Integer type;
     // Getter & Setter & toString
    }
    @Test
    public void testGroupBy(){
     List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
     // 奇偶数分组:奇数分一组,偶数分一组
     // groupingBy(Function<? super T, ? extends K> classifier) 参数是Function类型,Function返回值可以是要分组的条件,也可以是要分组的字段
     // 返回的结果是Map,其中key的数据类型为Function体中计算类型,value是List<T>类型,为分组的结果
     Map<Boolean, List<Integer>> result = list.stream().collect(Collectors.groupingBy(item -> item % 2 == 0));
     // {false=[1, 3, 5, 7, 9], true=[2, 4, 6, 8, 10]}
     System.out.println(result);
         // partitioningBy 用于分成两组的情况
     Map<Boolean, List<Integer>> twoPartiton = list.stream().collect(Collectors.partitioningBy(item -> item % 2 == 0));
     System.out.println(twoPartiton);
     
     
     User user = new User(1L, "zhangsan", 1);
     User user2 = new User(2L, "lisi", 2);
     User user3 = new User(3L, "wangwu", 3);
     User user4 = new User(4L, "fengliu", 1);
     List<User> users = Arrays.asList(user, user2, user3, user4);
     // 根据某个字段进行分组
     Map<Integer, List<User>> userGroup = users.stream().collect(Collectors.groupingBy(item -> item.type));
     /**
     * key 为要分组的字段
     * value 分组的结果
     * {
     * 1=[User{id=1, username='zhangsan', type=1}, User{id=4, username='fengliu', type=1}],
     * 2=[User{id=2, username='lisi', type=2}],
     * 3=[User{id=3, username='wangwu', type=3}]
     * }
     */
     System.out.println(userGroup);
    } 
    // 分组并对分组中的数据统计
    @Test
    public void testGroupBy2() {
         Foo foo1 = new Foo(1, 2);
     Foo foo2 = new Foo(2, 23);
     Foo foo3 = new Foo(2, 6);
     List<Foo> list = new ArrayList<>(4);
     list.add(foo1);
     list.add(foo2);
     list.add(foo3);
     Map<Integer, IntSummaryStatistics> collect = list.stream().collect(Collectors.groupingBy(Foo::getCode, Collectors.summarizingInt(Foo::getCount)));
     IntSummaryStatistics statistics1 = collect.get(1);
     IntSummaryStatistics statistics2 = collect.get(2);
     System.out.println(statistics1.getSum());
     System.out.println(statistics1.getAverage());
     System.out.println(statistics1.getMax());
     System.out.println(statistics1.getMin());
     System.out.println(statistics1.getCount());
     System.out.println(statistics2.getSum());
     System.out.println(statistics2.getAverage());
     System.out.println(statistics2.getMax());
     System.out.println(statistics2.getMin());
     System.out.println(statistics2.getCount());
    }

    累计操作

    @Test
    public void testReducing(){
     // sum: 是每次累计计算的结果,b是Function的结果
     System.out.println(Stream.of(1, 3, 4).collect(Collectors.reducing(0, x -> x + 1, (sum, b) -> {
     System.out.println(sum + "-" + b);
     return sum + b;
     })));
        
         // 下面代码是对reducing函数功能实现的描述,用于理解reducing的功能
     int sum = 0;
     List<Integer> list3 = Arrays.asList(1, 3, 4);
     for (Integer item : list3) {
     int b = item + 1;
     System.out.println(sum + "-" + b);
     sum = sum + b;
     }
     System.out.println(sum);
            
     // 注意reducing可以用于更复杂的累计计算,加减乘除或者更复杂的操作
     // result = 2 * 4 * 5 = 40
     System.out.println(Stream.of(1, 3, 4).collect(Collectors.reducing(1, x -> x + 1, (result, b) -> {
     System.out.println(result + "-" + b);
     return result * b;
     })));
    }


    转自:https://www.toutiao.com/i6817403401467331076/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1588570797&app=news_article&utm_source=weixin&utm_medium=toutiao_android&req_id=202005041339560101300361644B5CD9AD&group_id=6817403401467331076
  • 相关阅读:
    【leetcode】1442. Count Triplets That Can Form Two Arrays of Equal XOR
    【leetcode】1441. Build an Array With Stack Operations
    【leetcode】1437. Check If All 1's Are at Least Length K Places Away
    cxCheckCombobox
    修改现有字段默认值
    2018.01.02 exprottoexcel
    Statusbar OwnerDraw
    dxComponentPrinter记录
    单据暂存操作思路整理
    设置模式9(装饰者,责任链,桥接,访问者)
  • 原文地址:https://www.cnblogs.com/diandianquanquan/p/12826425.html
Copyright © 2011-2022 走看看