Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
  • Java语法

  • Java容器

  • Java新特性

    • Java8

      • 函数式接口
      • 方法引用
      • Stream流
        • Stream创建
        • 中间操作
          • 数据准备
          • filter
          • map
          • distinct
          • sorted
          • limit
          • skip
          • flatMap
          • 数学
        • 终结操作
          • collect
          • 查找与匹配
          • reduce归并
        • Optional
          • 创建对象
          • isPresent
          • 获取值
          • 过滤
          • 数据转换
        • 基本数据类型转换
      • Lambda表达式
  • IDEA常用快捷键
  • 正则表达式
  • API
  • 场景题

  • JavaSE
  • Java新特性
  • Java8
Nreal
2023-12-23
目录

Stream流

# Stream创建

  1. 单列集合

    Stream<Object> stream = list.stream();
    
    1
  2. 数组

    Integer[] arr = {1,2,3,4,5};
    Stream<Integer> stream = Arrays.stream(arr);
    Stream<Integer> stream2 = Stream.of(arr);
    
    1
    2
    3
  3. 双列集合

    Map<String,Integer> map = new HashMap<>();
    map.put("蜡笔小新",19);
    map.put("黑子",17);
    map.put("日向翔阳",16);
    Stream<Map.Entry<String,Integer>> stream = map.entrySet().stream();
    
    1
    2
    3
    4
    5

# 中间操作

# 数据准备

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Author {
    private Long id;
    private String name;
    private Integer age;
    private String intro;
    private List<Book> books;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Book {
    private Long id;
    private String name;
    private String category;
    private Integer score;
    private String intro;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# filter

条件过滤,符合过滤条件的才能继续留在流中;

//打印所有姓名长度大于1的作家的姓名
List<Author> authors = getAuthors();
authors.stream()
        .filter(author -> author.getName().length()>1)
        .forEach(author -> System.out.println(author.getName()));
1
2
3
4
5

# map

对流中的元素进行计算或转换;

//所有作家年龄+10
authors.stream()
        .map(author -> author.getAge())
        .map(age->age+10)
        .forEach(age-> System.out.println(age));
1
2
3
4
5

# distinct

去除流中的重复元素;

authors.stream()
        .distinct()
        .forEach(author -> System.out.println(author.getName()));
1
2
3

注意:distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以需要注意重写equals方法。

# sorted

//按照年龄降序排序
authors.stream()
        .distinct()
        .sorted((o1, o2) -> o2.getAge()-o1.getAge())
        .forEach(author -> System.out.println(author.getAge()));
1
2
3
4
5

如果调用空参的sorted()方法,需要流中的元素是实现了Comparable;

# limit

//按年龄排序,打印年龄最大的两个人姓名
authors.stream()
        .distinct()
        .sorted()
        .limit(2)
        .forEach(author -> System.out.println(author.getName()));
1
2
3
4
5
6

# skip

//按年龄排序,打印除了最大年龄的其余作家姓名
authors.stream()
        .distinct()
        .sorted()
        .skip(1)
        .forEach(author -> System.out.println(author.getName()));
1
2
3
4
5
6

# flatMap

map只能把一个对象转换成另一个对象来作为流中的元素;

flatMap可以把一个对象转换成多个对象作为流中的元素;

//打印所有书籍名字,对重复元素进行去重
authors.stream()
        .flatMap(author -> author.getBooks().stream())
        .distinct()
        .forEach(book -> System.out.println(book.getName()));
1
2
3
4
5

# 数学

  • max

    数组中:

    int max = Arrays.stream(nums).max().getAsInt();
    
    1
  • sum

    数组中:

    int sum = Arrays.stream(nums).sum();
    
    1

# 终结操作

# collect

流转换为一个集合

//获取一个存放所有作者名字的List集合
List<String> nameList = authors.stream()
                .map(author -> author.getName())
                .collect(Collectors.toList());
//获取一个Map集合,map的key为作者名,value为List<Book>
Map<String, List<Book>> map = authors.stream()
                .distinct()
                .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
1
2
3
4
5
6
7
8

# 查找与匹配

  1. anyMatch

    //判断是否有年龄在29以上的作家
    boolean flag = authors.stream()
            .anyMatch(author -> author.getAge() > 29);
    
    1
    2
    3
  2. allMatch

    //判断是否所有的作家都是成年人
    boolean flag = authors.stream()
        .allMatch(author -> author.getAge() >= 18);
    
    1
    2
    3
  3. noneMatch

    //判断作家是否都没有超过100岁的
    boolean b = authors.stream()
        .noneMatch(author -> author.getAge() > 100);
    
    1
    2
    3
  4. findAny

    //获取任意一个年龄大于18的作家,如果存在就输出他的名字
    Optional<Author> optionalAuthor = authors.stream()
            .filter(author -> author.getAge()>18)
            .findAny();
    
    optionalAuthor.ifPresent(author -> System.out.println(author.getName()));
    
    1
    2
    3
    4
    5
    6

# reduce归并

对流中的数据按照指定的计算方式计算出一个结果;

传入一个初始值,按照自定义的计算方式依次拿流中的元素和初始化值进行计算,计算结果再和后续的元素计算;

reduce两个参数的重载形式内部的计算方式如下:

T result = identity;
for (T element : this stream)
	result = accumulator.apply(result, element)
return result;
1
2
3
4

其中 identity就是我们可以通过方法参数传入的初始值,accumulator的 apply具体进行什么计算也是我们通过方法参数来确定的;

//使用reduce求所有作者年龄的和
Integer sum = authors.stream()
            .distinct()
            .map(author -> author.getAge())
            .reduce(0, (result, element) -> result + element);

//使用reduce求所有作者中年龄的最大值
Integer max = authors.stream()
            .map(author -> author.getAge())
            .reduce(Integer.MIN_VALUE, (result, element) -> result < element ? element : result);
1
2
3
4
5
6
7
8
9
10

# Optional

优雅得避免空指针异常;

# 创建对象

Optional的静态方法ofNullable来把数据封装成一个Optional对象;

Optional<Author> authorOptional = Optional.ofNullable(author);
1

# isPresent

会判断其内封装的数据是否为空,不为空时才会继续执行;

authorOptional.ifPresent(author -> System.out.println(author.getName()));
1

# 获取值

  • orElseGet

    获取数据并且设置数据为空时的默认值;

    如果数据不为空就能获取到该数据;

    如果为空则根据你传入的参数来创建对象作为默认值返回;

    Author author1 = authorOptional.orElseGet(() -> new Author());
    
    1
  • orElseThrow

    获取数据,如果数据不为空就能获取到该数据;

    如果为空则根据你传入的参数来创建异常抛出;

    Optional<Author> authorOptional = Optional.ofNullable(getAuthor());
    try {
        Author author = authorOptional.orElseThrow((Supplier<Throwable>) () -> new RuntimeException("author为空"));
        System.out.println(author.getName());
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
    
    1
    2
    3
    4
    5
    6
    7

# 过滤

使用filter方法对数据进行过滤;

如果原本是有数据的,但是不符合判断,也会变成一个无数据的Optional对象;

authorOptional.filter(author -> author.getAge()>100).ifPresent(author -> System.out.println(author.getName()));
1

# 数据转换

map

Optional<List<Book>> optionalBooks = authorOptional.map(author -> author.getBooks());
optionalBooks.ifPresent(books -> System.out.println(books));
1
2

# 基本数据类型转换

大量的数据不断的重复装箱拆箱的时候,时间损耗不可忽视;

Stream有关得基本数据类型转换:

mapToInt,mapToLong,mapToDouble,flatMapToInt,flatMapToDouble等;

ArrayList<Integer> list = new ArrayList<>();
list.stream()
    .mapToInt(x->x)
    .toArray();


authors.stream()
        .map(author -> author.getAge())
        .map(age -> age + 10)
        .filter(age->age>18)
        .map(age->age+2)
        .forEach(System.out::println);
1
2
3
4
5
6
7
8
9
10
11
12
方法引用
Lambda表达式

← 方法引用 Lambda表达式→

Theme by Vdoing | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式