Stream入门到实践

本文详细介绍了Java Stream API的使用,包括如何获取Stream、中间操作如filter、distinct、sorted、limit、skip和map,以及终止操作如forEach、allMatch、reduce和collect。通过实例展示了Stream在集合处理中的高效与便捷,强调了Stream的非存储特性和对原集合的无修改操作,同时提到了并行流的概念。
摘要由CSDN通过智能技术生成

什么是Stream

Stream是对集合对象的增强,专注于对集合对象进行各种便利的操作.

Stream相关的接口与方法

  • java.util.stream包下新增Stream类

  • Collection接口中新增stream()和parallelStream()默认方法

  • Arrays类中新增stream(T array)方法

使用流程

当我们使用一个流的时候,通常包括三个基本步骤:

获取一个数据源(source)→ 中间操作(数据转换)→终止操作(数据收集)。

代码

Stream操作中使用了lambda表达式,lambda表达式入门到实践

   @Test
    public void streamTest() {
        //需求:打印出集合中长度大于2的元素
        //创建集合
        List<String> list= Arrays.asList("AAA","B","CC","DDDD");
        //2.使用遍历方式打印
        for (String s: list) {
            if (s.length()>2){
                System.out.println(s);
            }
        }
        System.out.println("***************************");
        //3.使用Stream的方式
        //获取Stream流
        //进行中间操作(过滤)
        //进行终止操作(for循环打印)
        list.stream().filter(s -> s.length()>2).forEach(System.out::println);

    }

Stream获取

  • Collection.stream(): 集合对象获取串行流
  • Collection.parallelStream(): 集合对象获取并行流
  • Arrays.stream(T array): Arrays工具类方法获取
  • Stream.of(T… values)/Stream.of(T t): Stream静态方法获取

需要注意的是,对于基本数值型,目前有三种对应的包装类型 Stream:

IntStream、LongStream、DoubleStream。

代码
    @Test
    public void createStream() {
        //1.通过Collection.stream()方法创建Stream流
        //首先获取集合实列
        List<String> list= Arrays.asList("A","B","C","D");
        //获取Stream流
        Stream<String> stream = list.stream();

        //2.通过Collection.parallelStream()方法创建Stream流
        //获取Stream流
        Stream<String> parallelStream = list.parallelStream();

        //3.Arrays.stream(T array)方式获取
        //首先获取数组
        //注意:IntStream与Stream同为BaseStream的子类
        int[] array={1,2,3,4};
        IntStream intStream = Arrays.stream(array);

        //4.Stream.of(T... values)/Stream.of(T t)方式获取
        Stream<String> stringStream = Stream.of("A", "B", "C");
        
    }

Stream常见中间操作

  • filter: 从流中过滤某些元素
  • distinct: 筛选,通过流所生成元素的hashCode()和equals()去除重复元素。
  • sorted : 排序
  • limit: 设置流中元素数量的上限
  • skip: 跳过元素
  • map: 将元素转换成其他形式或提取信息。
代码

数据创建

public class User {

    //姓名
    private String name;
    //性别
    private String sex;
    //年龄
    private Integer age;

    public User(String name, String sex, Integer age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(name, user.name) &&
                Objects.equals(sex, user.sex) &&
                Objects.equals(age, user.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, sex, age);
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}

public class DataUtils {
    /**
     * 获取User集合
     *
     * @return
     */
    public static List<User> getUserList() {
        List<User> list = new ArrayList<>();
        User user1 = new User("张小凡", "男", 25);
        User user2 = new User("陆雪琪", "女", 26);
        User user3 = new User("碧瑶", "女", 24);
        User user4 = new User("兽神", "男", 1000);
        User user5 = new User("小白", "女", 500);
        User user6 = new User("田不易", "男", 100);
        User user7 = new User("林惊羽", "男", 25);
        User user8 = new User("张小凡", "男", 25);
        list.add(user1);
        list.add(user2);
        list.add(user3);
        list.add(user4);
        list.add(user5);
        list.add(user6);
        list.add(user7);
        list.add(user8);
        return list;
    }
}

  • filter
    @Test
    public void filterTest(){
        //需求:打印出全部男性角色
        List<User> list = DataUtils.getUserList();
        //获取stream流
        //使用filter方法进行过滤,传入lambda表达式
        //使用forEach打印
        list.stream().filter(value-> value.getSex().equals("男")).forEach(System.out::println);
    }

  • distinct
    @Test
    public void distinctTest(){
        //需求:打印出全部男性角色
        List<User> list = DataUtils.getUserList();
        //获取stream流
        //使用distinct去掉重复元素,已经重写了hashCode()和equals()方法
        //使用forEach打印
        list.stream().distinct().forEach(System.out::println);
    }
  • sorted
    @Test
    public void sortedTest() {
        //需求:按年龄从大到小进行排序
        List<User> list = DataUtils.getUserList();
        //可以实现Comparable接口也可使用Comparator接口,这里以Comparator方式举例
        //Comparator.comparingInt(User::getAge) 对age条件进行排序
        //reversed()方法是反序
        list.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).forEach(System.out::println);
    }
  • limit
    @Test
    public void limitTest() {
        //需求:打印年龄最小的两个元素
        List<User> list = DataUtils.getUserList();
        //可以实现Comparable接口也可使用Comparator接口,这里以Comparator方式举例
        //Comparator.comparingInt(User::getAge) 对age条件进行排序
        //reversed()方法是反序
        //limit 设置最大数量
        list.stream().sorted(Comparator.comparingInt(User::getAge)).limit(2).forEach(System.out::println);
    }
  • skip
    @Test
    public void skipTest() {
        //需求:从第二个元素开始全部遍历
        List<User> list = DataUtils.getUserList();
        list.stream().skip(1).forEach(System.out::println);
    }
  • map
    @Test
    public void mapTest() {
        //需求:获取name的集合
        List<User> list = DataUtils.getUserList();
        //获取stream流
        //去掉重复元素
        //获取元素中的名称
        //数据收集
        List<String> stringList = list.stream().distinct().map(User::getName).collect(Collectors.toList());
        System.out.println(stringList);
    }

Stream终止操作

  • forEach: 遍历操作
  • allMatch: 检查是否匹配所有元素
  • anyMatch: 检查是否至少匹配一个元素
  • noneMatch: 检查是否没有匹配所有元素
  • findFirst: 返回第一个元素
  • findAny: 返回当前流中的任意元素
  • count: 返回流中元素的总个数
  • max: 返回流中最大值
  • min: 返回流中最小值
  • reduce: 归约操作
  • collect : 收集,将流转行成想要的结果
代码

Stream终止操作,Stream如果不调用终止操作的方法,中间操作不会执行,执行完一次终止操作之后,流不能继续使用

  • match
    @Test
    public void matchTest() {
        //需求:判断年龄是否都大于18岁
        List<User> list = DataUtils.getUserList();
        //获取stream流
        //进行匹配操作
        boolean allMatch = list.stream().allMatch(user -> user.getAge() >= 18);
        System.out.println(allMatch);
        //anyMatch与noneMatch操作类似
    }
    @Test
    public void reduceTest() {
        //需求:求集合中元素总年龄
        List<User> list = DataUtils.getUserList();
        //获取stream流
        //将User转成Integer
        //进行求和
        Integer sum = list.stream().map(User::getAge).reduce(0, Integer::sum);
        System.out.println(sum);
    }

collect

常用的Collectors.toList()/Collectors.toSet()

    @Test
    public void collectTest() {
        //需求:将获取年龄的集合从小到大排列
        List<User> list = DataUtils.getUserList();
        //获取stream流
        //将User转成Integer
        //进行排序
        //数据搜集
        List<Integer> integers = list.stream().map(User::getAge).distinct().sorted().collect(Collectors.toList());
        System.out.println(integers);
    }

总结

  • Stream不是数据结构,而是对集合的操作API
  • Stream用到lambda表达式
  • Stream不存储数据,只从数据源中读取数据
  • Stream操作不改变原集合,产生新的数据
  • Stream流可以进行多次中间操作,不执行终止操作时,中间操作不会执行.执行一次终止操作后,流就不可用
  • Stream支持并行化,并不需要自己编写多线程代码

引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值