Java SE Stream流

Java SE Stream流


  Java8 API添加了一个新的抽象称为流 Stream ,可以让你以一种声明的方式处理数据。

  Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对Java 集合运算和表达的高阶抽象

 Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。

1、定义

  对数据源中的数据,进行运行|计算的元素序列。

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

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算
  • 数据源 流的来源。 可以是集合,数组等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

注意:

  • 数组|集合可以作为存储数据的数据源,stream不能存储数据,只能对数据源中的数据进行计算,得到新的结果,得到一个新的stream
  • stream不会影响数据源中的数据
  • 流是一次性的流,使用过一次以后不能再次使用,每次会得到一个新的流
  • stream流特点: 延迟执行|惰性加载 : 进行一些列中见操作的时候,如果没有进行终止行为,就不会执行中间操作,会在进行终止行为的时候统一执行

2、Stream的操作三个步骤

1、创建Stream

一个数据源(如:集合、数组),获取一个流

2、中间操作

一个中间操作链,对数据源的数据进行处理

3、终止操作

一个终止操作,执行中间操作链,并产生结果

2.1、创建Stream

使用步骤:

  • 1.根据数据源获取流
  • 2.一些列流式的中间操作
  • 3.终止行为

注意:

  • 1、Stream自己不会存储元素·
  • 2、Stream不会改变源对象。相反,会返回一个持有结果的新Stream。
  • 3、Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行。
/*** StreamAPI三个操作步骤: 
* 1、创建Stream * 
2、中间操作 * 
3、终止操作 
*/
			//1.Arrays.stream(数组)
        int[] arr = {1,2,3,4,5,6};
        IntStream stream1 = Arrays.stream(arr);

        //2.Collection的实现类 stream()
        List<String> ls = List.of("aaa","bbb","ccc");
        Stream<String> stream2 = ls.stream();

        //parallelStream 并行流
        stream2 = ls.parallelStream();

        //3.Stream.of(数据1,数据2,数据3)
        Stream<Integer> s = Stream.of(1,2,3,4,5);

        //终止行为
        stream1.forEach(System.out::println);
        stream2.forEach(System.out::println);
        s.forEach(System.out::println);

2.2、中间操作

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

2.2.1、筛选与切片
  • filter;过滤
  • limit;截断流,使其元素不超过给定数量
  • skip;跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流。
  • distinct;去重
 public static void main(String[] args) {
        //
        Set<User> list=Set.of(
                new User(101,"张三",18),
                new User(102,"李四",20),
                new User(103,"王五",30),
                new User(104,"赵六",16),
                new User(105,"孙七",20)
        );

        //获取流
        Stream<User> stream = list.stream();
        //过滤filter
        //条件: 找到年龄》=18随的用户信息
        // limit(num)-截断流,使其元素不超过给定数量
         skip-跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流。
        //distinct 去重 (按照重写hashcode与equals方法相等去重)
        stream.filter(user -> {
            System.out.println("过滤年龄》=18随的用户信息");
            return  user.getMoney()>=18;
        }).limit(3).skip(1).distinct().forEach(System.out::println);

    }
2.2.2 、排序

sorted(Comparable)-自然排序

sorted(Comparator)-定制排序

public static void main(String[] args) {
        List<User> lst=List.of(
                new User(101,"张三",18),
                new User(102,"李四",20),
                new User(103,"王五",30),
                new User(104,"赵六",16),
                new User(105,"孙七",20)
        );
   Stream<User> stm=lst.stream();
   // //默认根据内部比较器排序
   stm.sorted().forEach(System.out::println);

   //默认根据外部比较器排序
   stm.sorted((o1,o2)->Integer.compare(o2.getNo(), o1.getNo())).forEach(System.out::println);
}
2.2.3 map排序(重要)
  • 中间操作 map : 把流操作的每一个数据,当作function接口中抽象的参数传递,根据指定的实现行为(lambda)得到一个结果,最终把所有的结果返回一个新的流。

    • 如果每一个结果都是一个流,最终会返回一个存放每一个流的一个新的流-》流中存放流
  • flatMap: 作用与map相等,特点中每一个数据必须返回一个流,最终会结合称为一个整个流 --》 流中存放数据

public static void main(String[] args) {
        List<User> lst=List.of(
                new User(101,"张三",18),
                new User(102,"李四",20),
                new User(103,"王五",30),
                new User(104,"赵六",16),
                new User(105,"孙七",20)
        );
        Stream<User> stm=lst.stream();
         //获取所有用户的年龄,然后升序排序 Map
        //stm.map(user -> user.getName()).sorted().forEach(System.out::println);

			//流中放流
        stm.map(user -> {
                List<Character> ls=new ArrayList<>();
                char[] arr=user.getName().toCharArray();
            for (char ch:arr) {
                ls.add(ch);
            }
            return ls.stream();
        }).sorted().forEach(System.out::println);
        //{{a,b,c},{a,b,d},{a,a,a}}

        //flatMap 返回值比逊是个流
        stm.flatMap(u->{
            List<Character> ls = new ArrayList<>();
            char[] arr = u.getName().toCharArray();
            for(char ch:arr){
                ls.add(ch);
            }
            return ls.stream();
        }).forEach(System.out::println); //{{zhang,san,b,c}

2.3、终止操作

2.3.1、reduce 归约
public static void main(String[] args) {
        List<User> list = Arrays.asList(
                new User(01 ,"张三", 18),
                new User(02 ,"李四", 38),
                new User(02 ,"李四", 38),
                new User(05 ,"王五", 50),
                new User(04 ,"赵六", 16),
                new User(03 ,"田七", 28)
        );

        Stream<User> stream = list.stream();
        //Optional<T> reduce(BinaryOperator<T> accumulator)
        // 把流操作的前两个数据作为抽象方法的参数,经过运算得到结果,
        // 结果作为下一次计算的第一个参数,流操作的下一个数据作为第二个参数,重复,最终得到结果返回

        Double sum=stream.map(User::getMoney)
                .distinct().sorted()
                .reduce((x,y)-> x+y).get();

        System.out.println(sum);

        // // T reduce(T identity, BinaryOperator<T> accumulator);
        // 把第参数100作为抽象方法的第一个参数,流操作的数据作为第二个参数,
        // 经过运算得到结果,结果作为下一次计算的第一个参数,流操作的下一个数据作为第二个参数,重复,最终得到结果返回
        Double ssum = stream.map(User::getMoney)
                .distinct().sorted()
                .reduce(1000D,(x,y)->{
                    System.out.println(x+"-->"+y);
                    return x+y;
                });
        System.out.println(ssum);

        //了解
        //并行流
        System.out.println(List.of(1,2,3,4,5).parallelStream()
                .reduce(1000,(x,y)->{
                    System.out.println(Thread.currentThread().getName()+" : "+x+"-->"+y);
                    return x+y;
                },(x,y)->{
                    System.out.println("结果:"+" : "+x+"-->"+y);
                    return x+y;
                }));
    }
2.3.2 查找与匹配
 public static void main(String[] args) {
        List<User> list = Arrays.asList(
                new User(01 ,"张三", 18),
                new User(02 ,"李四", 38),
                new User(02 ,"李四", 38),
                new User(05 ,"王五", 50),
                new User(04 ,"赵六", 16),
                new User(03 ,"田七", 28)
        );

        Stream<User> stream = list.stream();

        // allMatch-检查是否匹配所有元素
        System.out.println(stream.allMatch(u->u.getAge()>=0));;
   			// noneMatch-检查是否没有匹配所有元素
   			// findFirst-返回第一个元素
   			// findAny-返回当前流中的任意元素
   			// count-返回流中元素的总个数
   
				// max-返回流中最大值 
   			// 需求:获取工资最高的员工信息
        System.out.println(stream.max((x,y)->x.getAge()-y.getAge()).get());;

        //收集所有用户的姓名,返回一个存储姓名的集合
       /* List<String> names = stream.map(User::getName).collect(Collectors.toList());
        System.out.println(names);*/
				//自动去重
        System.out.println(stream.map(User::getName).collect(Collectors.toSet()));
				//手动去重
        Map<Integer,String> map = stream.distinct().collect(Collectors.toMap(User::getId,User::getName));
        System.out.println(map);
    }
2.3.3、收集(了解)

收集-将流转换为其他形式,接收一个Collertor接口的实现,用于给Stream中元素做汇总的方法

// 需求:获取当前公司所有员工的姓名添加到集合中 
// List-把流中所有元素收集到List中 
List<String> list = emps.stream() 
			.map(Employee::getName) 
			.collect(Collectors.toList()); 
list.forEach(System.out::println);
// Set-把流中所有元素收集到Set中,删除重复项 
Set<String> set = emps.stream() 
		.map(Employee::getName) 
		.collect(Collectors.toSet()); 
set.forEach(System.out::println);
// Map-把流中所有元素收集到Map中,当出现相同的key时会抛异常 
Map<String, Integer> map = emps.stream() 
		.collect(Collectors.toMap(Employee::getName, Employee::getAge)); 
System.out.println(map);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值