史上最全 函数式编程-Stream流 教程,学会了再也没有看不懂的java代码

示例

在这里插入图片描述

1、Lambda表达式

1)基本格式

        (参数列表) -> {代码}
        匿名内部类上  alt+回车  可以自动生成Lambda表达式

2)eg1、创建线程

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("...");
    }
}).start();

// 接口中只有一个抽象方法需要重写
// 关注的是 run 方法的参数和 方法体
new Thread(()->{
    System.out.println("...");
    }
).start();

3)eg2、IntBinaryOperator

public static int calculateNum(IntBinaryOperator operator) {
    int a = 10;
    int b = 20;
    return operator.applyAsInt(a, b);
}
public static void main(String[] args) {
    int res = calculateNum(new IntBinaryOperator() {
        @Override
        public int applyAsInt(int left, int right) {
            return left + right;
        }
    });
    res = calculateNum(((int left, int right) -> {
        return left + right;
    }));
    // 进一步简化
    res = calculateNum((left, right) -> left + right);
}

2、Stream流

1)使用目的

        可以更方便的地操作集合

2)数据准备

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Book {

    private Integer bookId;
    private String bookName;

}
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Author {

    private Integer id;
    private String name;
    private List<Book> books;

}

3)快速入门

推荐先用匿名内部类写,再用 alt + 回车 生成 lambda 表达式

public static void main(String[] args) {
    List<Author> authors = getAuthors();
    authors.stream()    // 把集合转换成流
            .distinct() // 去重
            .filter(author -> author.getId() < 2)   // 取 id < 2 的元素
            .forEach(author -> System.out.println(author.getId()));// 终结操作
}
private static List<Author> getAuthors() {
    List<Author> authors = new ArrayList<>();
    Author aa = new Author(1, "aa", null);
    Author dd = new Author(1, "aa", null);
    Author bb = new Author(2, "bb", null);
    Author cc = new Author(3, "cc", null);
    authors.add(aa);
    authors.add(dd);
    authors.add(bb);
    authors.add(cc);
    return authors;
}

操作数组:Arrays.stream(数组名);
       或者:Stream.of(数组名);
操作双列集合:

HashMap<Integer, String> map = new HashMap<>();
Stream<Map.Entry<Integer, String>> stream = map.entrySet().stream();

4)中间操作

a、filter

       筛选过滤

b、map

       对流中元素进行计算或映射

List<Author> authors = getAuthors();
// 从 Author 中提取 name 并转换为 String 类型
authors.stream()    // 把集合转换成流
        .map(Author::getName)
        .forEach(System.out::println);
authors.stream()    // 把集合转换成流
        .map(Author::getId)	// 提取 id
        .map(id -> id + 10)	// 将 id + 10 再输出
        .forEach(System.out::println);

c、distinct

       去重,依赖 Object 的 equals 方法,如果要自定义去重规则,可以重写 equals 方法

d、sorted

       排序

authors.stream()    // 把集合转换成流
        .distinct() // 去重
        .sorted((o1, o2) -> o2.getId() - o1.getId())    // id 降序,不要记这个,容易记错,最好的方法是测试,不对就换个顺序即可
        .forEach(System.out::println);

e、limit

       设置流的最大长度,超出部分将被抛弃

authors.stream()    // 把集合转换成流
        .distinct() // 去重
        .sorted((o1, o2) -> o2.getId() - o1.getId())    // id 降序
        .limit(2)   // 取前两个元素
        .forEach(System.out::println);

f、skip

       跳过前 n 个元素

authors.stream()    // 把集合转换成流
        .distinct() // 去重
        .sorted((o1, o2) -> o2.getId() - o1.getId())    // id 降序
        .skip(2)    // 跳过前面 2 个元素
        .forEach(System.out::println);

g、flatMap

       相比于 map,flatMap 可以将一个对象转换为多个对象作为流中元素,常用于对象中有集合对象的情况

authors.stream()    // 把集合转换成流
        .flatMap(author -> author.getBooks().stream())
        .forEach(System.out::println);

5)终结操作

a、forEach

       遍历流

b、count

       获取流中的元素个数

c、min&max

       获取流中的最值

Optional<Integer> max = authors.stream()    // 把集合转换成流
        .flatMap(author -> author.getBooks().stream())
        .map(Book::getBookId)
        .max((o1, o2) -> o2 - o1);// 对 book_id 降序排序并取最大值
System.out.println(max.get());

d、collect

       将当前流转化为集合

List<String> list = authors.stream()    // 把集合转换成流
        .map(Author::getName)
        .collect(Collectors.toList());  // 提取 作家名 并转换为 List
System.out.println(list);
Map<String, List<Book>> map = authors.stream()    // 把集合转换成流
        .distinct() // 去重
        .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
System.out.println(map);

e、查找与匹配

anyMatch

       判断是否有任意符合匹配条件的元素,返回值为 boolean

allMatch

       判断是否所有元素都符合匹配条件,返回值为 boolean

noneMatch

       判断是否所有元素都不符合匹配条件,返回值为 boolean

findAny

       获取流中任意一个元素,可以设置条件

findFirst

       获取流中第一个元素,可以设置条件

f、reduce 归并

       将流中的数据按照自己制定的计算方式计算出一个结果(缩减操作),其具体作用是把stream中的元素组合起来,我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和初始化值进行计算,计算结果在和后面的元素进行计算

Integer sum = authors.stream()    // 把集合转换成流
        .distinct()
        .map(Author::getId)
        .reduce(0/*初始值*/, (result/*初始值*/, element/*流中元素*/) -> result + element);
System.out.println(sum);

3、Optional

       作用:避免空指针异常

4、函数式接口

       只有一个抽象方法的接口,通常都在接口上加上@FunctionalInterface注解进行标识验证,但无论加不加,只要接口中只有一个抽象方法,都叫做函数式接口

5、方法引用

1)引用类的静态方法

       类名::方法名

2)引用对象的实例方法

       对象名::方法名

3)引用类的实例方法

       类名::方法名

4)构造器引用

       类名::new

6、高级用法-并行流

1)定义

       当流中有大量元素时,可以使用并行流提高效率,运用在多线程环境中

2)用法

Integer sum = authors.stream()    // 把集合转换成流
        .parallel() // 使用并行流
        .distinct()
        .map(Author::getId)
        .reduce(0/*初始值*/, (result/*初始值*/, element/*流中元素*/) -> result + element);
System.out.println(sum);
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值