Steram流(简介、创建Stream、中间操作(筛选、切片和排序)、终止操作(查找、匹配和收集))

一、简介

Java8 API添加了一个新的抽象称为流 Stream ,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流,流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等
    Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。

二、Stream的操作三个步骤

  1. 创建Stream
    一个数据源(如:集合、数组),获取一个流
  2. 中间操作
    一个中间操作链,对数据源的数据进行处理
  3. 终止操作
    一个终止操作,执行中间操作链,并产生结果

1.创建Stream

        //创建集合
        List<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("bbbb");
        list.add("ccccc");
        list.add("dddddd");
        list.add("eeeeeee");
        // 1、可以通过Conllection系列集合提供的顺序流stream()或并行流 parallelStream()
        Stream<String> stream = list.stream();
        // 2、通过Arrays中的静态方法stream()获取数据流
        int[] ints={1,2,3,4,5,6,7,8};
        IntStream stream1 = Arrays.stream(ints);
        // 3、通过Stream类中的静态方法of()
        Stream<String> stream2 = Stream.of("aa", "bb", "cc");

        String[] str=new String[10];
        Stream<String> str1 = Stream.of(str);

2.Stream的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理,而在终止操作时一次性全部处理,称为”惰性求值”。
定义一个工具类,用于获取集合和bean类
工具类

public class ListUtil {
    public static List<String> getList(){
        List<String> list = new ArrayList<>();
        list.add("aaaa");
        list.add("bbbbbb");
        list.add("ddddddd");
        list.add("eee");
        list.add("ffff");
        return list;
    }

    public  static List<Person> getListPerson(){
        return Arrays.asList(new Person[]{
                new Person("张三",19),
                new Person("李四",18)}
                );

    }
}

Person类

public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
[1]筛选和切片

1.filter和limit

//创建集合
        List<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("bbbb");
        list.add("ccccc");
        list.add("dddddd");
        list.add("eeeeeee");

        //打印长度超过5的元素
        System.out.println("---------打印长度超过5的元素--------");
        Stream<String> stream =list.stream();
        stream.forEach(t->{
            if (t.length()>5)
                System.out.println(t);
        });
        // 将满足条件的那些元素临时存放(假的)一个新的流
        Stream<String> stream1 = list.stream().filter(t -> t.length() > 5);
        stream1.forEach(t-> System.out.println(t));
        //stream1.forEach(t-> System.out.println(t));
        System.out.println("=========filter筛选============");
        //(1)filter正常写法
        list.stream().filter(t->t.length()>6).forEach(t-> System.out.println(t));
        //方法引用
        list.stream().filter(t->t.length()>5).forEach(System.out::println);

        System.out.println("----------limit截取-----------");
        // limit截断流,使其元素不超过给定数量
        list.stream().limit(3).forEach(System.out::println);

在这里插入图片描述
2.skip跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空 流

 //获取list集合
        List<String> list = ListUtil.getList();
        System.out.println("====list集合中的数据为======");
        System.out.println(list);
        System.out.println("----筛选长度>3的字符串后跳过两个元素----");
        //list集合中字符串长度>3的字符串,跳过2个后的到的数据为
        list.stream().filter(t->t.length()>3).skip(2).forEach(t-> System.out.println(t));

在这里插入图片描述
3.distinct通过流所生产元素的hashCode()和equals()去除重复元素

//获取list集合
        List<String> list = ListUtil.getList();
        System.out.println("====list集合中的数据为======");
        System.out.println(list);
        System.out.println("-----使用distinct去重复-----");
        //通过流所生产元素的hashCode()和equals()去除重复元素
        list.stream().distinct().forEach(System.out::println);

在这里插入图片描述

[2] 排序

sorted(Comparable)-自然排序

 //获取list集合数据
        List<String> list = ListUtil.getList();
        System.out.println("====list集合中的数据为======");
        System.out.println(list);
        //根据字符串长度排序list集合
        System.out.println("------根据字符串长度排序list集合-------");
        list.stream().sorted((t1,t2)->{
            return t1.length()-t2.length();
        }).forEach(System.out::println);

        //获取泛型为Person对象的list集合
        List<Person> listPerson = ListUtil.getListPerson();
        System.out.println("----listPerson中的数据为-------");
        System.out.println(listPerson);
        //根据年龄排序集合中的数据
        listPerson.stream().sorted((t1,t2)->{
            return t1.getAge()-t2.getAge();
        }).forEach(System.out::println);
        //只获取成年人的信息
        System.out.println("=====成年人的信息为======");
        listPerson.stream().filter(t->t.getAge()>=18).forEach(System.out::println);

在这里插入图片描述

3.终止操作

[1]查找与匹配
//获取list集合数据
        List<String> list = ListUtil.getList();
        System.out.println("====list集合中的数据为======");
        System.out.println(list);
        //allMatch检查是否匹配所有元素
        //判断|查看 集合中的元素字符个数是否都大于3个
        System.out.println("集合中元素字符个数是否都>3个:"+list.stream().allMatch(t -> t.length() > 3));
        //判断|查看 集合中的元素字符个数是否存在大于3个字符的情况
        System.out.println("集合中是否有元素大于3个:" + list.stream().anyMatch(t -> t.length() > 3));

        //获取list流中第一个元素
        Optional<String> first = list.stream().findFirst();
        //获取first中的值
        System.out.println(first.get());
        //获取first中的值,如果没有元素,则返回none
        System.out.println(first.orElse("none"));

        //findAny为获取任意一个元素,但在普通流中,默认获取的是第一个
        System.out.println(list.stream().findAny().get());
        //在parallelStream流中,获取的是随机的
        System.out.println(list.parallelStream().findAny().get());

        //统计字符长度大于3的元素个数
        System.out.println("字符串长度>3的元素个数"+list.stream().filter(t -> t.length() > 3).count());
        //获取listPerson
        List<Person> listPerson = ListUtil.getListPerson();
        System.out.println("-----获取listPerson中的元素为------");
        System.out.println(listPerson);
        System.out.println("返回两参数的较大值"+listPerson.stream().max((t1, t2) -> {
            return t1.getAge() - t2.getAge();
        }));
[2]收集
		 List<Employee> emps = Arrays.asList(
                new Employee("张三", 18, 3333.33),
                new Employee("李四", 38, 4444.44),
                new Employee("王五", 50, 5555.55),
                new Employee("赵六", 16, 6666.66),
                new Employee("田七", 28, 7777.77) );

        // 需求:获取当前公司所有员工的姓名添加到集合中
        // List-把流中所有元素收集到List中
        List<String> nameList = emps.stream().map(Employee::getName).collect(Collectors.toList());
        nameList.forEach(System.out::println);
        // Set-把流中所有元素收集到Set中,删除重复项
        Set<String> nameSet = emps.stream().map(Employee::getName).collect(Collectors.toSet());
        nameSet.forEach(System.out::println);
        // Map-把流中所有元素收集到Map中,当出现相同的key时会抛异常
        Map<String, Integer> empMap = emps.stream().collect(Collectors.toMap(Employee::getName, Employee::getAge));
        empMap.forEach((k,v)-> System.out.println(k+" "+v));

        // 员工总数
        Long collect = emps.stream().collect(Collectors.counting());
        System.out.println("员工总数为:"+collect);
        // 工资平均数
        Double salAvg = emps.stream().collect(Collectors.averagingDouble(Employee::getSal));
        System.out.println("平均工资数:"+salAvg);

        // 工资总和
        DoubleSummaryStatistics salCum = emps.stream().collect(Collectors.summarizingDouble(Employee::getSal));
        System.out.println("工资总和为:"+salCum);
        // 工资最大值的员工
        Optional<Employee> op = emps.stream().collect(Collectors.maxBy((t1, t2) -> Double.compare(t1.getSal(), t2.getSal())));
        System.out.println(op.get());
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值