JDK1.8的Stream API学习

Stream的学习

流的本质

是数据渠道,用于操作数据源(集合,数组等)所生成的元素序列。
“集合讲的是数据,流讲的是计算!”

注意

①Stream 自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream.
③Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Stream操作的三个步骤
步骤

创建Stream --一个数据源,获取一个流
中间操作–对数据源的数据进行操作
终止操作–产生结果

创建Stream
// 1.可以通过Collection 系列集合提供的stream()或parallelStream()
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();

        // 2.通过Arrays 中的静态方法stream() 获取数组流
        Employee[] emps = new Employee[10];
        Stream<Employee> stream2 = Arrays.stream(emps);

        // 3.通过Stream 类中的静态方法of()
        Stream<String> stream3 = Stream.of("aa", "bb", "ddd");

        // 4.创建无线流
            //迭代
        Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 20);
中间操作

中间操作:多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理! 而在终止操作时一次性全部处理,称为“惰性求值”。

中间操作的种类

筛选与切片
filter:接收Lambda ,从流中排除某些元素。
limit:截断流, 使其元素不超过给定的数量。
skip(n): 跳过元素,返回一个扔掉了前N个元素的流。若流中的元素不足N个,则返回一个空流。与limit(N)互补。
distinct:筛选,通过流所生成元素的hashcode()和equals()去重复元素

// 中间操作不会执行任何操作
List<Employee> employees = Arrays.asList(
            new Employee("张三",18,9999.99),
            new Employee("李四",38,4555.66),
            new Employee("王五",50,6666.66),
            new Employee("赵六",16,7777.77),
            new Employee("田七",8,8888.88)
    );
  @Test
  public void test1(){
      // 中间操作不会执行任何操作
      Stream<Employee> employeeStream = employees.stream()
              .filter((e) -> {
                 System.out.println("Stream API 的中间操作 ");
                  return e.getAge() > 35;
               });

      // 触发终止操作 所有操作全部执行
      employeeStream.forEach(System.out::println);
    }

    @Test
    public void test2(){
        employees.stream()
                .filter((e) -> e.getSalary() > 5000)
                .limit(2)
                .forEach(System.out::println);
    }

映射
map:接收Lambda ,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatMap:接收一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有流连成一个流。

	@Test
    public void test4(){
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
        list.stream()
                .map((str) -> str.toUpperCase())
                .forEach(System.out::println);

        System.out.println("----------------------");

        // 提取名字
        employees.stream()
                .map(Employee::getName)
                .forEach(System.out::println);

        System.out.println("----------------------");
        
        //map 的使用 相当于集合中 add
        Stream<Stream<Character>> stream1 = list.stream()
                .map(StreamTest2::filterCharacter);//{{a,a,a},{b,b,b}}

        stream1.forEach((sm) ->
                sm.forEach(System.out::println));

        System.out.println("----------------------");

		//flatMap 的使用  相当于集合中的addALL
        Stream<Character> stream2 = list.stream()
                .flatMap(StreamTest2::filterCharacter);//{a,a,a,b,b,b}

        stream2.forEach(System.out::println);

    }

    // 将字符串中字母拿出来放到集合中,返回该集合的流
    public static Stream<Character> filterCharacter(String str){
        List<Character> list = new ArrayList<>();

        for (Character ch : str.toCharArray()) {
            list.add(ch);
        }
        return list.stream();
    }

排序
sorted() :自然排序(comparable)
sorted(comparator com ) :定制排序

  		// 自然排序
        List<String> list = Arrays.asList("aaa","ccc", "ddd", "ppp", "bbb", "eee");
        list.stream()
                .sorted()
                .forEach(System.out::println);

        // 定制排序
        employees.stream()
                .sorted((e1, e2) -> {
                    if(e1.getAge().equals(e2.getAge())){
                        return e1.getName().compareTo(e2.getName());
                    }else{
                        return e1.getAge().compareTo(e2.getAge());
                    }
                }).forEach(System.out::println);
终止操作

查找与匹配
* allMatch:检查是否匹配所有元素
* anyMatch:检查是否至少匹配一个元素
* noneMatch:检查是否没有匹配所有元素
* findFirst:返回第一个元素
* findAny:返回当前流中的任意元素
* count:返回流中元素的总个数
* max:返回流中最大值
* min:返回流中最小值

List<Employee> employees = Arrays.asList(
            new Employee("张三",18,9999.99, Employee.Status.FREE),
            new Employee("李四",38,4555.66, Employee.Status.BUSINESS),
            new Employee("王五",50,6666.66, Employee.Status.FREE),
            new Employee("赵六",16,7777.77, Employee.Status.BUSINESS),
            new Employee("田七",8,8888.88, Employee.Status.VOCATION)
    );


    @Test
    public void test(){
        boolean b = employees.stream()
                .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSINESS));
        System.out.println(b);//false

        boolean b1 = employees.stream()
                .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSINESS));
        System.out.println(b1);//true

        boolean b2 = employees.stream()
                .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSINESS));
        System.out.println(b2);//false

        // Optional 容器类 减少控制针异常 相当于数据库中的IFNULL
        Optional<Employee> op = employees.stream()
                .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
                .findFirst();
        // 获取工资最低的员工信息
        System.out.println(op.get());

        /**
         *  parallelStream():并行流,多个线程同时去找,谁先找到,返回谁
         *  stream():串行流,一个接一个去找
         */
        Optional<Employee> op2 = employees.parallelStream()
                .filter((e) -> e.getStatus().equals(Employee.Status.FREE))
                .findAny();
        System.out.println(op2.get());

        //总数 员工工资大于5000的员工人数有?
        long count = employees.stream()
                .filter((e) -> e.getSalary() > 5000)
                .count();
        System.out.println(count);

        //返回流中最大值 员工中最高工资是那位员工?
        Optional<Employee> op3 = employees.stream()
                .max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(op3.get());

        //返回流中最小值  员工中最低工资是?
        Optional<Double> op4 = employees.stream()
                .map(Employee::getSalary)
                .min(Double::compare);
        System.out.println(op4.get());
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值