java8中list流--stream


在日常的开发工作中经常需要用到list的相关操作,例如遍历,排序,筛选,替换等操作,今日也学习并认识到了list流的一些基础操作,在这里总结一下常用的操作。

Stream

首先来认识一下stream
在java8中stream提供了很多Api,通过这些Api以及Lamda表达式可以进行许多高效并且遍历的操作

创建stream流

创建流有四种方式,具体使用如下:

	 @Test
    /**
     * 通过Collection集合创建流
     */
    public void create1(){
        Stream<Person> stream = personList.stream();//创建顺序流
        Stream<Person> personStream = personList.parallelStream();//创建并行流
    }

    @Test
    /**
     * 通过数组创建流
     */
    public void create2(){
        Stream<Person> stream = Arrays.stream(personArr);
    }

    @Test
    /**
     * 通过stream中的of()方法创建流
     */
    public void create3(){
        Stream<Person> stream = Stream.of(new Person("emp1", "1"), new Person("emp2", "2"));
    }

    @Test
    /**
     * 无限流创建,流中的元素无限多
     * 1.iterate():该方法需要传入一个初始值
     * 2.generate():该方法不需要初始值
     */
    public void create4(){
        Stream.iterate(0,n -> n+1);//生成初始值为0,后续元素依次加一的流
        Stream.generate(Math::random);//生成一个随机元素的流
    }

中间操作

筛选操作

	@Test
    /**
     *筛选操作  filter(Predicate p)
     * 需要传入一个接口,接口的返回值为boolean类型
     */
    public void operate1(){
        //通过filter()方法筛选列表中性别为“1”的数据
        Stream<Person> stream = personList.stream().filter(e -> e.getSex().equals("1"));
    }

    @Test
    /**
     * 截断操作 limit(long maxSize)
     * 需要传入一个值,截断流,使其元素不会超过给定的数量
     */
    public void operate2(){
        //筛选第一个元素
        Stream<Person> stream = personList.stream().limit(1);
    }

    @Test
    /**
     * 跳过元素 skip(long n)
     * 跳过元素,返回一个扔掉了前 n 个元素的流
     * 当列表中的元素不足 n 个的时候,则返回一个空流
     */
    public void operate3(){
        Stream<Person> stream = personList.stream().skip(1);
    }

    @Test
    /**
     * 去重筛选 distinct()
     * 通过流中元素的hashcode()和equals()方法进行去重
     */
    public void operate4(){
        Stream<Person> stream = personList.stream().distinct();
    }

映射操作

  	@Test
    /**
     * 映射操作 map(function f)
     * 接收一个函数作为参数,将元素转换为其他形式或是提取信息
     * 该函数会应用到每一个元素上,并将其映射成一个新的元素
     */
    public void operate5(){
        //筛选列表中姓名包含“2”的元素并得到他们的姓名
        //先筛选,筛选后提取姓名得到新的String类型的流
        Stream<String> stream = personList.stream()
                .filter(e -> e.getName().contains("2"))
                .map(Person::getName);
    }

排序操作

	@Test
    /**
     * 排序操作 sorted()  sorted(Comparator com)
     * 第一种是自然排序方式
     * 第二种是需要制定排序的方式
     */
    public void operate6(){
        //首先演示一个普通的整形列表的自然排序
        List<Integer> intList = Arrays.asList(1, 2, 5, 4, 3);
        intList.stream().sorted().forEach(System.out::println);
        //输出结果为由小到大排序   1,2,3,4,5

        //接下来演示一个针对自定义类列表的指定排序
        List<Employee> employees = Arrays.asList(new Employee("员工一", 35, 5000.31),
                new Employee("员工二", 30, 8000.31),
                new Employee("员工三", 30, 5000.00));
        //对员工列表进行排序,排序规则:根据年龄由小到大排序,再根据工资由小到大排序
        employees.stream().sorted((e1,e2) ->{
                    int ageCompare = Integer.compare(e1.getAge(),e2.getAge());
                    if(ageCompare != 0){
                        return ageCompare;
                    }else{
                        return Double.compare(e1.getSalary(),e2.getSalary());
                    }
                }).forEach(System.out::println);
        //查询结果:
        //Employee{name='员工三', age=30, salary=5000.0}
        //Employee{name='员工二', age=30, salary=8000.31}
        //Employee{name='员工一', age=35, salary=5000.31}
    }

终止操作

为什么需要终止操作呢?
因为stream是惰性的,我们前面所用到的中间操作实际上是没有进行的,只有我们进行了终止操作也就是意味着我们需要最终结果的时候,才会去执行相关的中间操作,因此,我们通过stream流操作数据时,终止操作时必不可少的。

匹配、查找

	@Test
    /**
     * allMatch(Predicate p)
     * 检查是否匹配所有元素
     */
    public void end1(){
        //如果所有员工的年龄都大于30则返回true,否则返回false
        boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 30);
    }

    @Test
    /**
     * anyMatch(Predicate p)
     * 检查是否至少匹配一个元素
     */
    public void end2(){
        //如果有一个员工的年龄为30岁则返回true,否则返回false
        boolean anyMatch = employees.stream().anyMatch(e -> e.getAge() == 30);
    }

    @Test
    /**
     * noneMatch(Predicate p)
     * 检查是否没有匹配的元素
     */
    public void end3(){
        //如果没有员工的年龄小于18岁则返回true,否则返回false
        boolean noneMatch = employees.stream().noneMatch(e -> e.getAge() < 18);
    }

    @Test
    /**
     * findFirst --- 返回第一个元素
     * findAny --- 返回当前流中的任意一个元素
     */
    public void end4(){
        Optional<Employee> first = employees.stream().findFirst();
        Optional<Employee> any = employees.stream().findAny();
    }

    @Test
    /**
     * count() --- 返回流中元素的数量
     * max(Comparator c) --- 返回流中的最大值
     * min(Comparator c) --- 返回流中的最小值
     */
    public void end5(){
        //返回流中元素的数量
        long count = employees.stream().count();
        //返回年龄最大的员工
        Optional<Employee> max = employees.stream()
                .max((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));

        //返回年龄最小的员工
        Optional<Employee> min = employees.stream()
                .min((e1,e2) -> Integer.compare(e1.getAge(),e2.getAge()));
    }

    @Test
    /**
     * foreach(Consumer c)内部迭代操作
     */
    public void end6(){
        employees.stream().forEach(System.out :: println);
    }

规约

 	@Test
    /**
     * 规约:可以将流中元素反复结合,得到一个值
     * reduce(T identity,BinaryOperator)
     * 需要传入一个初始值和计算方式
     * reduce(BinaryOperator)
     * 需要传入计算方式
     */
    public void reduce1(){
        //计算一个整形列表的元素相加之和
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        Integer reduce = list.stream().reduce(5, Integer::sum);

        //计算员工列表中所有员工工资累加之和
        Optional<Double> optional = employees.stream().map(e -> e.getSalary()).reduce(Double::sum);
    }

收集

 	 @Test
    /**
     * 收集:将流转换为其他形式,接收一个Collector接口的实现
     * Collect(Collector c)
     * Collector接口中方法的实现决定了如何对流执行收集操作(例如收集到list,map等)
     */
    public void collect1(){
        //收集为list
        List<Employee> list = employees.stream().collect(Collectors.toList());
        //收集为set
        Set<Employee> set = employees.stream().collect(Collectors.toSet());
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值