Java Steam流处理入门

最近工作开始写java,复习一下java 的lambda,stream,Optional操作

lambda表达式

不关心名字,只关心具体操作,其实就是对匿名内部类的优化

基本格式 ()-{}

参数类型可以省略

只有一个参数,小括号可以省略

只有一个语句,大括号,分号都可以省略,如果是return ,return也要省略

stream流

概述

更方便的对集合或者数组进行链状流式操作

入门

authors.stream()
    .distince() //去重
    .filter((author) -> {
        return auther.getAge() < 18;
    }) //过滤,测试接口 年龄小于18
    .forEach((author) -> {
        System.out.print(author);
    })  //消费性接口

常用操作

创建流

单列集合:集合对象.stream()

authors.stream()

数组:Arrays.stream(数组)或者Stream.of()

Integer[] nums = {1,2,3,4,5};
Arrays.stream(nums);
Stream.of(nums);

双列集合:转换成单列在创建

HashMap<String,String> map = new HashMap<>();
//转换成单列集合,在创建
map.entrySet().stream()

中间操作

filter:根据传入的条件进行判断过滤

authors.stream()
    .distince() //去重
    .filter((author) -> {
        return auther.getName().length() > 1;
    }) //过滤,测试接口 年龄小于18
    .forEach((author) -> {
        System.out.print(author);
    })  //消费性接口

map:对流的元素进行计算或者转换,进行转换

authors.stream()
    .distince() //去重
    .map((author) -> {
        return auther.getName();
    }) //map转换
    .forEach((name) -> {
        System.out.print(name);
    })  //消费性接口

distinct:去重,依赖equals方法,所以对象必须重写equals

authors.stream()
    .distince() //去重
    .map((author) -> {
        return auther.getName();
    }) //过滤,测试接口 年龄小于18
    .forEach((name) -> {
        System.out.print(name);
    })  //消费性接口

sorted : 传入比较函数,不传就会用对象自己的实现比较方法comparable 接口

authors.stream()
    .distince() //去重
    .sorted((o1, o2) -> {
        return o1.getAge()-o2.getAge();
    }) //排序
    .forEach((name) -> {
        System.out.print(name);
    })  //消费性接口

llimit:限制最大长度

authors.stream()
    .distince() //去重
    .sorted((o1, o2) -> {
        return o1.getAge()-o2.getAge();
    }) //排序
    .limit(2)
    .forEach((name) -> {
        System.out.print(name);
    })  //消费性接口

skip:跳过

authors.stream()
    .distince() //去重
    .sorted((o1, o2) -> {
        return o1.getAge()-o2.getAge();
    }) //排序
    .skip(1)
    .limit(2)
    .forEach((name) -> {
        System.out.print(name);
    })  //消费性接口

flapMap:将一个对象转换成多个对象,多个对象平铺

authors.stream()
    .distince() //去重
    .flapMap((author) ->{
    	return author.getBooks().stream();
    })
    .forEach((name) -> {
        System.out.print(name);
    })  //消费性接口
authors.stream()
    .flapMap((author) ->{
    	return author.getBooks().stream();
    })
    .flapMap((boos) ->{
    	return Arrays.stream(book.getCategory().split(","));
    })
    .distince()
    .forEach((category) -> {
        System.out.print(name);
    })  //消费性接口

终结操作

forEach :消费型接口

authors.stream()
    .flapMap((author) ->{
    	return author.getBooks().stream();
    })
    .flapMap((boos) ->{
    	return Arrays.stream(book.getCategory().split(","));
    })
    .distince()
    .forEach((category) -> {
        System.out.print(name);
    })  //消费性接口

count:统计数目

authors.stream()
    .flapMap((author) ->{
    	return author.getBooks().stream();
    })
    .flapMap((boos) ->{
    	return Arrays.stream(book.getCategory().split(","));
    })
    .distince()
    .count()

max/min:获取最值

authors.stream()
    .flapMap((author) ->{
    	return author.getBooks().stream();
    })
    .map((boos) ->{
    	return boos.getScore();
    })
    .max((o1, o2) -> {
        return o1 - o2;
    });

collect:收集器

authors.stream()
    .flapMap((author) ->{
    	return author.getBooks().stream();
    })
    .map((boos) ->{
    	return boos.getScore();
    })
    .collect(Collectors.toList());
authors.stream()
    .flapMap((author) ->{
    	return author.getBooks().stream();
    })
    .map((boos) ->{
    	return boos.getScore();
    })
    .collect(Collectors.toSet());

转map (使用多),传入两个参数,一个转key,注意key不为空,不可以重复,一个转value

authors.stream()
    .collect(Collectors.toMap((author) ->{
    	return author.getName();
    }, (author) -> {
    	return author.getBooks();
    }));
  • 查找匹配:

anyMatch :任意一个匹配,返回true

authors.stream()
    .anyMatch((author) ->{
    	return author.getAge() > 29;
    })

noneMatch 一个都匹配不上,为true

allMatch:全部匹配上

authors.stream()
    .allMatch((author) ->{
    	return author.getAge() > 29;
    })

findAny:随机获取的,无法保证获取哪一个,可能为空,optional对象接受

authors.stream()
    .findAny()

findFirst:获取第一个

authors.stream()
    .findFirst()

reduce:归并计算(缩紧操作)

authors.stream()
    .map(author -> author.getAge())
    //指定初始值和计算操作
    .reduce(0, (res, ele) ->{
    	return res + ele;
    })
authors.stream()
    .map(author -> author.getAge())
    //指定初始值和计算操作
    .reduce(Integer.MIN_VALUE, (res, ele) ->{
    	return ele > res ? ele : res;
    })

1个参数,不传入初始值,会把遍历的第一个元素作为初始值,然后计算

authors.stream()
    .map(author -> author.getAge())
    //指定初始值和计算操作
    .reduce((res, ele) ->{
    	return res + ele;
    })

注意

  1. 惰性求值,必须要有终结操作
  2. 一次性流,只能使用一次
  3. 不会影响原来集合的数据

optional使用

  1. 创建optional
Optional<Author> op = Optional.ofNullable(author);
op.ifPresent((author) -> System.out.print(author)) //消费型接口,非空执行

Optional.of() //这个必须传非空的对象
Optional.empty() //返回空的
  1. 安全消费
op.ifPresent((author) -> System.out.print(author)) //消费型接口,非空执行
  1. 安全获取值
op.orElseGet(() -> new Author();)// 不存在则,获取默认值
op.orElseThrow(() -> new RuntimeException("null");)// 不存在则,抛出一个自定义异常
  1. 过滤数据
op.filter(author -> author.getAge > 18) // 返回Optional对象,过滤掉不符合的数据
  1. 判断
isPresent(author) ,没啥用和 null != author 一个样子
  1. 数据转换
op.map((author) -> {
	return author.getBooks();
})

函数式接口

建议加上@FunctionalInterface 注解进行标记,但是无论是否加上注解,只要接口中只有一个抽象方法,那就是函数式接口

常用函数式接口

  1. Consumer 消费接口

    传入一个参数,进行消费,无返回值

  2. Function 计算转换接口

    传入一个参数进行计算或者转换,然后返回结果

  3. Predicate 判断接口

    传入一个参数,判断,返回true or false

  4. Supplier 生产形接口

  5. BiConsumer,BiFunction,BiPredicate 等接口,提供两个参数

方法引用

什么情况下可以使用方法引用?如果只调用了一种方法,就可以

基本格式

类名或者对象名::方法名

类的静态方法

调用的是类的静态方法,并且参数按照顺序传入,就可以使用。

authors.stream()
    .map(String::valueOf)

对象的实例方法

调用的是对象的实例方法,并且参数按照顺序传入,就可以使用。

StringBuilder sb = new StringBuilder();
authors.stream()
    .map(sb::append)

引用类的实例方法

调用的是引用类的成员方法,调用了第一个参数的成员方法,并且剩余的参数按照顺序传入,就可以使用。其实这个和类的静态方法调用差不多,就是第一个参数的成员方法,也可以这么写。

StringBuilder sb = new StringBuilder();
authors.stream()
    .map(类名::方法名)

构造器引用

类名::new ,调用的是构造方法

基本数据类型优化

注意基本数据类型和引用类型的自动拆箱装箱的消耗

例如mapToInt,mapToLong,mapToDouble,flatmapToInt,flatmapToLong,flatmapToDouble

authors.stream()
    .mapToInt(author -> author.getAge()) //直接转换成基本数据类型,避免拆箱装箱损耗
    .map(age -> age + 10)

并行流

stream.parallel() //转化成为并行流

authors.paralleStream() // 直接获得并行流

stream.peek() //调试方法,中间操作,可以虚假消费,来进行输出调试,不会真正消费数据
posted @ 2025-07-13 17:43  Aotle  阅读(59)  评论(0)    收藏  举报