函数式编程

函数式编程

函数式编程思想:对方法中的数据进行了什么操作

优点:代码简介、便于理解、易于并发编程

1.Lambda表达式

JDK8中的语法糖,可以对某些匿名内部类的写法进行简化
使用条件:匿名内部类是一个接口,并且接口只有一个抽象方法
核心原则:可推导可省略
基本格式
(参数列表)->{代码}
案例一

//未使用lambda
         new Thread(new Runnable() {
             @Override
             public void run() {
                 System.out.println("第一个线程启动了");
             }
         }).start();
//使用lambda
          new Thread(()->
          {
             System.out.println("第二个线程启动了"); 
          }).start();
        }

案例二
选中接口类,alt+enter,可进行匿名内部类与lambda表达式的转换

//自定义方法,方法参数为抽象接口,且只有一个接口方法
  public static int calculateNum(IntBinaryOperator operator)
    {
        int a=10;
        int b=20;
        return operator.applyAsInt(a,b);
    }
//未进行lambda表达式
       int i = calculateNum(new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        });
        System.out.println(i);
//lambda表达式
     int i = calculateNum((int left, int right) -> {
            return left + right;
        });
        System.out.println(i);

案例三

public class Main {
    public static void main(String[] args) {
        foreachArr((int abc)->
        {
            System.out.println(abc);
        });
    }
    public static void foreachArr(IntConsumer intConsumer)
    {
        int[] arr={1,2,3,4,5,6,7,8,9,10};
        for (int i:arr) {
            intConsumer.accept(i);
        }
    }
}

终结:使用lambda表达式的时候,需要关注的是抽象类中的抽象方法参数与方法体
函数式编程_第1张图片
Lambda表达式省略机制:
1.参数类型可省略
2.方法体只有一句代码时大括号return和唯一一句代码的分号可省略
3.方法只有一个参数时,小括号可以省略

2.Stream流

可以将数组或集合进行链状流式的操作不同于io流

//去重distinct()
//过滤filter()
//foreach遍历
  List<Author> authors = test();
            authors.stream().distinct().
                    filter(new Predicate<Author>() {
                        @Override
                        public boolean test(Author author) {
                            return author.getAge() > 18;
                        }
                    })
                    .forEach(new Consumer<Author>() {
                        @Override
                        public void accept(Author author) {
                            System.out.println(author.getName());
                        }
                    });
//lambda表达式
 List<Author> authors = test();
            authors.stream().distinct().
                    filter(author -> author.getAge() > 18)
                    .forEach(author -> System.out.println(author.getName()));                    
    }

stream的常见操作
一.创建流
1.单列集合:集合对象.stream()
2.数组:Arrays.stream(数组)或者使用Stream.of
3.双列集合:转换成单列集合后在创建
函数式编程_第2张图片
二.中间操作
1.filter,过滤
2.map,可以把流中的元素进行计算或转换
函数式编程_第3张图片
函数式编程_第4张图片
3.distinct,除去重复项
4.sorted,排序
函数式编程_第5张图片
如果使用的是空参的sorted方法,需要流中的元素实现了Comparable

4.limit,设置流的最大长度,超出的部分抛弃
例如:取排行榜的前三名
5.skip,跳过流中的n个元素,返回剩下的元素
6.flatMap
函数式编程_第6张图片
三.终结操作
1.foreach,对流中的元素进行遍历
2.count,统计数量
3.max&min,获取最值
4.collect,把流转换成集合

set集合
函数式编程_第7张图片
list集合
函数式编程_第8张图片
map集合,key值需要去重
函数式编程_第9张图片
5.查找与匹配,用来判断是否有符合匹配条件的元素,结果boolean
anyMatch,任何符合条件的
allMatch,都符合条件
noneMatch,没有符合条件的
findAny,获取流中的任意一个元素

//由于是随机取数,使用findAny方法返回值可能为空,

使用findAny进行匹配,如果有值则输出,没有值则无操作
函数式编程_第10张图片
findFirst,查找第一个元素

6.reduce归并
将stream流中的数据进行归并,即遍历处理流中的数据
案例一
函数式编程_第11张图片
案例二函数式编程_第12张图片
Stream流的注意事项
1.没有终结操作,不会执行语句
2.流是一次性的,一旦进行终结操作,这个流就不能再用了
3.正常情况下,在流中处理数据不会影响原数据

函数式编程_第13张图片

3.并行流

parallel()
将串行流改为并行流,多个线程一同处理数据,提高工作效率,减少耗时

4.函数式接口

概述:只有一个抽象方法的接口
如果想要自定义函数式接口,需要在接口类上方添加@FunctionalInterface注解
函数式编程_第14张图片

5.Optional

检验和避免出现空指针异常
1.Optional对象的创建Optional.ofNullable()
函数式编程_第15张图片
2.安全消费值,即不报空指针错误
ifPresent()
在这里插入图片描述
orElseGet()
函数式编程_第16张图片
orElseThrow
函数式编程_第17张图片
3.数据过滤
filter
在这里插入图片描述
4.判断
函数式编程_第18张图片
5.数据转换
map
函数式编程_第19张图片

6.方法引用

作用:使用lambda表达式的时候,对表达式进行简化
使用条件:方法体中只有一个方法的调用,包含构造方法,我们可以对代码进行进一步简化
格式=类名或对象名::方法名,可以使用alt+enter进行快捷简化
函数式编程_第20张图片

你可能感兴趣的:(java)