首页 > 编程语言 >Java8新特性3:Stream流

Java8新特性3:Stream流

时间:2022-10-27 14:37:54浏览次数:72  
标签:java Stream 特性 userList User import new Java8 user

回顾之前《JavaSE-23.2》:
https://www.cnblogs.com/yppah/p/14900824.html
https://www.cnblogs.com/yppah/p/14900829.html
https://www.cnblogs.com/yppah/p/14900834.html
https://www.cnblogs.com/yppah/p/14900837.html
https://www.cnblogs.com/yppah/p/14900847.html


1 什么是stream流

Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

image-20221025164432309

2 创建stream流

// 创建stream流的两种方式
userList.stream(); //并行流,采用多线程执行,数据量比较少的时候
userList.parallelStream(); //串行流,采用单线程执行,数据量比较大的时候

// parallelStream效率比Stream高
//原理:Fork join 将一个大的任务拆分n多个小的子任务并行执行,最后在统计结果,有可能会非常消耗cpu的资源,确实可以提高效率。
//注意:数据量比较少的情况下,不要使用并行流。

3 Stream将list转换为Set

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/25 16:47
 */
public class Test01 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));
        userList.add(new User("amy", 22)); //对象的属性值重复;但两个对象不相等
        User user = new User("sam", 23);
        userList.add(user);
        userList.add(user); //对象(存储地址)重复;可去重

        /*// 创建stream流的两种方式
        userList.stream(); //并行流,采用多线程执行
        userList.parallelStream(); //串行流,采用单线程执行
        // parallelStream效率比Stream要高*/

        //利用stream将list转为set
        Stream<User> userStream = userList.stream();
        Set<User> userSet = userStream.collect(Collectors.toSet());
        userSet.forEach(t -> System.out.println(t));
    }
}

image-20221026084650164

4 set集合去重底层原理剖析[经典面试题]

set集合的底层去重原理 - 小杜打醋尢买布 - 博客园 (cnblogs.com)

list集合去重_谈谈Java中Set集合去重的原理 - 记性这么差 - 博客园 (cnblogs.com)

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/26 8:45
 */
public class Test01_2 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));
        userList.add(new User("jack", 19));
        userList.add(new User("jack", 19));

        System.out.println("list未去重:");
        userList.forEach(user -> System.out.println(user));

        System.out.println("set以下为去除重复后:");
        Stream<User> userStream = userList.stream();
        Set<User> userSet = userStream.collect(Collectors.toSet());
        userSet.forEach(t -> System.out.println(t));
    }
}

image-20221027135828279


package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.HashMap;
import java.util.HashSet;

/**
 * @Author: haifei
 * @Date: 2022/10/27 13:57
 */
public class Test01_3 {

    public static void main(String[] args) {
        /*
        Object类中equals()默认是比较两者内存地址是否相等
        此处自定义的User类并未重写equals(),则直接比较两对象的地址
        String类重写了equals()
         */
        User user1 = new User("jack", 19);
        User user2 = new User("jack", 19);
        System.out.println("user1.equals(user2): " + user1.equals(user2)); //false
        System.out.println("user1==user2: " + (user1==user2)); //false

        String str1 = "jack";
        String str2 = "jack";
        System.out.println("str1.equals(str2): " + str1.equals(str2)); //true
        System.out.println("str1==str2: " + (str1==str2)); //true

        /*
        set集合底层依赖于map集合实现防重复key
        map集合底层基于equals比较防重复key,结合hashcode
         */
        HashSet<String> strHashSet = new HashSet<>();
        strHashSet.add(str1);
        strHashSet.add(str2);
        HashMap<Object, Object> objectHashMap = new HashMap<>();
        objectHashMap.put(user1, "a");
        objectHashMap.put(user2, "b");
        //此时map会装两个不同的key,因为两个对象地址不同,即为两对象不相等
        objectHashMap.forEach((k,v)-> System.out.println("k:" + k + ", v:" + v));

        //此处,若User类中重写了equals()和hashcode(),则两对象相等,map中只存储一个key
        //因此,上一.java中则会实现去重
    }
}

image-20221027142018077


image-20221027141624287

image-20221027141602372

image-20221027141705112

image-20221027141746763

image-20221027141814219

image-20221027141851189

image-20221027141918529

5 Stream将list转换为Map

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/26 16:50
 */
public class Test02 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));

        Stream<User> userStream = userList.stream();
        /*Map<String, User> userMap = userStream.collect(Collectors.toMap(
                new Function<User, String>() {
                    @Override
                    public String apply(User user) {
                        return user.getUserName(); //键
                    }
                },
                new Function<User, User>() {
                    @Override
                    public User apply(User user) {
                        return user; //值
                    }
                })
        );
        userMap.forEach(new BiConsumer<String, User>() {
            @Override
            public void accept(String s, User user) {
                System.out.println(s + "," + user);
            }
        });*/

        /*Map<String, User> userMap = userStream.collect(Collectors.toMap(
                user -> {
                    return user.getUserName(); //键
                },
                user -> {
                    return user; //值
                })
        );*/
        Map<String, User> userMap = userStream.collect(Collectors.toMap(user -> user.getUserName(), user -> user));
        userMap.forEach((s, user) -> System.out.println(s + "," + user));
    }
}

image-20221026170830077

6 通过reduce求和

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.stream.Stream;

/**
* @Author: haifei
* @Date: 2022/10/26 17:35
*/
public class Test03 {

   public static void main(String[] args) {
       Stream<Integer> stream = Stream.of(10, 50, 30, 10);
//        Optional<Integer> reduce = stream.reduce(new BinaryOperator<Integer>() {
//            @Override
//            public Integer apply(Integer i1, Integer i2) {
//                return i1 + i2;
//            }
//        });
       Optional<Integer> reduce = stream.reduce((i1, i2) -> i1 + i2);
       System.out.println(reduce.get()); //100


       List<User> userList = new ArrayList<>();
       userList.add(new User("lili", 16));
       userList.add(new User("tom", 26));
       userList.add(new User("amy", 22));
       userList.add(new User("sam", 23));
       Stream<User> userStream = userList.stream();
       /*Optional<User> sumAge = userStream.reduce(new BinaryOperator<User>() {
           @Override
           public User apply(User u1, User u2) {
               User user = new User("sumAge", u1.getAge() + u2.getAge());
               return user;
           }
       });*/
       Optional<User> sumAge = userStream.reduce((u1, u2) -> {
           User user = new User("sumAge", u1.getAge() + u2.getAge());
           return user;
       });
       System.out.println(sumAge.get().getAge()); // 87
   }
}

image-20221026191234466

7 Max和Min

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/26 19:13
 */
public class Test04 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));
        userList.add(new User("sam", 23));

        Stream<User> userStream = userList.stream();
        /*Optional<User> max = userStream.max(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getAge() - o2.getAge();
            }
        });*/
        Optional<User> max = userStream.max((o1, o2) -> o1.getAge() - o2.getAge());

        //java.lang.IllegalStateException: stream has already been operated upon or closed
        //记得要重新创建流再求min,要是接着上面的userStream用会报错
        Stream<User> userStream2 = userList.stream();
        /*Optional<User> min = userStream2.min(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getAge() - o2.getAge();
            }
        });*/
        Optional<User> min = userStream2.min((o1, o2) -> o1.getAge() - o2.getAge());
        System.out.println("max age:" + max.get().getAge());
        System.out.println("min age:" + min.get().getAge());
    }
}

image-20221026192324507

8 Match匹配

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/26 19:24
 */
public class Test05 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));
        userList.add(new User("sam", 23));

        Stream<User> stream = userList.stream();
        /*boolean isAnyMatch = stream.anyMatch(new Predicate<User>() {
            @Override
            public boolean test(User user) {
                return "tom".equals(user.getUserName());
            }
        });*/
        boolean isAnyMatch = stream.anyMatch(user -> "tom".equals(user.getUserName()));
        System.out.println(isAnyMatch); //只要匹配一条记录就是true,一条也没有则false

        Stream<User> stream2 = userList.stream();
        /*boolean isAllMatch = stream2.allMatch(new Predicate<User>() {
            @Override
            public boolean test(User user) {
                return "tom".equals(user.getUserName());
            }
        });*/
        boolean isAllMatch = stream2.allMatch(user -> "tom".equals(user.getUserName()));
        System.out.println(isAllMatch); //只有每条记录都匹配才是true,否则为false
    }
}

image-20221026193213136

9 Fliter过滤器

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/26 19:34
 */
public class Test06 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("lili", 20));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));
        userList.add(new User("sam", 23));

        //where userName="lili" and age > 18
        Stream<User> stream = userList.stream();
        /*stream.filter(new Predicate<User>() {
            @Override
            public boolean test(User user) {
                return "lili".equals(user.getUserName()) && user.getAge() > 18;
            }
        }).forEach(user -> System.out.println(user));*/
        stream.filter(user -> "lili".equals(user.getUserName()) && user.getAge() > 18)
                .forEach(user -> System.out.println(user));
    }
}

image-20221026194343765

10 Limit和Skip

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/26 19:51
 */
public class Test07 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));
        userList.add(new User("sam", 23));
        userList.add(new User("jack", 30));

        Stream<User> stream = userList.stream();
        stream.limit(2).forEach(user -> System.out.println(user)); //limit(0,2),[从第0条往后]取前两条
        System.out.println("===========================");
        Stream<User> stream2 = userList.stream();
        stream2.skip(2).limit(3).forEach(user -> System.out.println(user)); //limit(2,3),从第2条后取3条
    }
}

image-20221027093011285

11 Sorted排序

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/27 9:31
 */
public class Test08 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));
        userList.add(new User("sam", 23));
        userList.add(new User("jack", 30));

        Stream<User> stream = userList.stream();
        /*stream.sorted(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o2.getAge()-o1.getAge(); //前o1-后o2升序;后o2-前o1降序
            }
        }).forEach(user -> System.out.println(user.toString()));*/
        stream.sorted(
                (o1, o2) -> (o2.getAge()-o1.getAge())
        ).forEach(
                user -> System.out.println(user.toString())
        );
    }
}

image-20221027093933249

12 Stream综合案例

package com.yppah.myStream;

import com.yppah.myLambda.p6.User;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
 * @Author: haifei
 * @Date: 2022/10/27 9:40
 */
public class Test09 {

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("lili", 16));
        userList.add(new User("tom", 26));
        userList.add(new User("amy", 22));
        userList.add(new User("sam", 23));
        userList.add(new User("sam", 16));
        userList.add(new User("sam", 35));
        userList.add(new User("sam22", 23));
        userList.add(new User("sam33", 30));
        userList.add(new User("jack", 30));

        // 需求:对数据流的数据实现降序排列、且名称为sam、获取前两位进行打印
        Stream<User> stream = userList.stream();
        /*stream.sorted(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o2.getAge()-o1.getAge();
            }
        }).filter(new Predicate<User>() {
            @Override
            public boolean test(User user) {
                return "sam".equals(user.getUserName());
            }
        }).limit(2).forEach(user -> System.out.println(user));*/
        stream.sorted((o1, o2) -> o2.getAge()-o1.getAge())
                .filter(user -> "sam".equals(user.getUserName()))
                .limit(2)
                .forEach(user -> System.out.println(user)); //forEach是终止操作,其之后当前stream流不再可用
    }
}

image-20221027095125998

13 并行流底层实现原理

package com.yppah.myStream;

import java.time.Duration;
import java.time.Instant;
import java.util.OptionalLong;
import java.util.function.LongBinaryOperator;
import java.util.stream.LongStream;

/**
 * @Author: haifei
 * @Date: 2022/10/27 10:46
 */
public class Test10 {

    public static void main(String[] args) {

        // 单线程:13330ms  13290ms   13s左右
        Instant start = Instant.now();
        long sum = 0;
        for (long i=0; i<=50000000000L; i++) {
            sum += i;
        }
        System.out.println(sum);
        Instant end = Instant.now();
        System.out.println("五百亿求和花费时间:" + Duration.between(start, end).toMillis());


        // 并行流: 11035ms   11636ms   11s左右
        Instant start2 = Instant.now();
        LongStream longStream = LongStream.rangeClosed(0, 50000000000L);
        /*OptionalLong reduce = longStream.parallel().reduce(new LongBinaryOperator() {
            @Override
            public long applyAsLong(long left, long right) {
                return left + right;
            }
        });*/
        OptionalLong reduce = longStream.parallel().reduce((left, right) -> left + right);
        System.out.println(reduce.getAsLong());
        Instant end2 = Instant.now();
        System.out.println("五百亿求和花费时间:" + Duration.between(start2, end2).toMillis());
        /*
        原理:
            底层是多线程
            处理大的任务拆分成n多小任务,最后将计算结果合并
         */
    }
}


单线程

image-20221027115232147

多线程

image-20221027115255007

标签:java,Stream,特性,userList,User,import,new,Java8,user
From: https://www.cnblogs.com/yppah/p/16479680.html

相关文章

  • Java中getResourceAsStream方法返回null
    原因:我存放资源的文件并不是源根,所以我们的方法是无法访问到的。所以返回null指针!解决办法:鼠标右键点击要读取配置文件的文件夹将文件夹标记成ResourcesRoot就可以......
  • CentOS8 安装 jdk8 / java8的教程(推荐)
    前言最开始我是想在CentOS8上使用wget下载,然后对它进行解压,配置环境变量,奈何搞了很长时间都没有搞好,于是放弃,使用yum直接安装。1、安装方法CentOS8上使用......
  • Java Stream流的使用
    流相关的方法可以分为三种类型,分别是:获取Stream流、中间方法、终结方法。中间方法会返回当前流,可以方便的进行链式调用。流不可重复使用,否则会报错:java.lang.IllegalSta......
  • jdk16(jdk16新特性)
    jdk1.6怎么配置环境变量在path的值后面加个“;”,在粘贴如下地址:“E:\ProgramFiles\Java\jdk1.6.0_03\bin;”,盘符就是你安装JDK的盘符,不一定是E的哈,我是安在E盘的。然后新建一......
  • C++标准库字符串流sstream
    sstream与strstream在C++有两种字符串流,一种在<strstream>中定义,另一种在<sstream>中定义,两者的区别如下:strstream里包含strstreambuf、istrstream、ostrstream、strst......
  • Java8新特性-Stream
    一、Stream(流)1.1简介1.是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。2.集合讲的是数据,流讲的是计算。3.延迟方法:调用Stream方法之后返回的还是Stream......
  • Java8新特性-函数式接口
    一、函数式接口1.1简介首先的是一个接口接口内有且只有一个抽象方法为防止破坏函数式接口,最好是在接口上使用@FunctionalInterface注解修饰定义一个函数接口pa......
  • 【RocketMQ入门到精通】— RocketMQ初级特性能力 | Message Order,RocketMQ的消息可以
    名言警句任何先进的技术均与魔法无异追本溯源​​经历了6个月的失踪,我将带着干货终究归来!【RocketMQ入门到精通】​​订阅与发布消息的发布是指某个生产者向某个topic发送消......
  • 云服务的7个数据特性​
    云服务的搭建需要将许多数据特性考虑在内,包含物理特、性能要求、易变性、容量、监管要求、事务边界、保存期限7个方面,所有这些数据需求都会对如何存储底层数据造成决策影响......
  • java8 Steam流及Optional的使用
    目录Stream流:获取流1.list获取:2.Map获取3.数组获取流方法分类:1.forEach(终结方法)2.count计数(终结方法)3.filter过滤4.limit截取5.skip跳过6.map映射7.concat组合8.dis......