函数式编程

定义

程序可以用一系列的数学函数表达;

JAVA实现

  1. Stream 类 + Lambda + 函数式接口
    Stream 类用来支持通过“.”级联多个函数操作的代码编写方式;引入 Lambda 表达式的作用是简化代码编写;函数接口的作用是让我们可以把函数包裹成函数接口,来实现把函数当做参数一样来使用(Java 不像 C 一样支持函数指针,可以把函数直接当参数来使用)。

“.”表示调用某个对象的方法。为了支持上面这种级联调用方式,我们让每个函数都返回一个通用的类型:Stream 类对象。在 Stream 类上的操作有两种:中间操作和终止操作。中间操作返回的仍然是 Stream 类对象,而终止操作返回的是确定的值结果。我们再来看之前的例子。我对代码做了注释解释,如下所示。其中,map、filter 是中间操作,返回 Stream 类对象,可以继续级联其他操作;max 是终止操作,返回的不是 Stream 类对象,无法再继续往下级联处理了。


public class FPDemo {
  public static void main(String[] args) {
    Optional<Integer> result = Stream.of("f", "ba", "hello") // of返回Stream<String>对象
            .map(s -> s.length()) // map返回Stream<Integer>对象
            .filter(l -> l <= 3) // filter返回Stream<Integer>对象
            .max((o1, o2) -> o1-o2); // max终止操作:返回Optional<Integer>
    System.out.println(result.get()); // 输出2
  }
}```

## Lambda表达式
Lambda是一个匿名函数(相似于匿名内部类),作用是返回一个实现了接口的对象. 简化创建实现接口的对象的过程.
Lambda只能用于函数式接口(只有一个抽象方法的接口, 用注解@FunctionalInterface标识)
Lambda的基本语法
小括号() : 形式参数列表
大括号{} : 描述方法体
-> : Lambda运算符(读作goes to),用于分割上面两个元素
//一个没有参数, 没有方法体的Lambda表达式
()->{}
写法:省略实现接口的类名、省区接口名、省区方法名字,保留核心的参数,函数内容;
优势
Lambda表达式比起传统的匿名内部类, 其优势就是有很多可省略的地方, 相较而言更简洁明了.
Lambda表达式可省略的原则: 凡是可根据上下文推断得到的, 就可以省去.

![在这里插入图片描述](https://img-blog.csdnimg.cn/e392da79fb5f45b096df1ee4dfee6ab8.png)
方法(函数)引用
方法引用返回的类型不再是接口的实例对象.
为什么需要它
当我们使用多个 接口实现对象 , 它们执行的指令相同. 但如果后面要改, 那么修改成本很高. 那么把这些指令单独出来成为一个方法, 就可以解决这个问题.
所以方法引用只能适用于方法已存在的情况
格式
“方法的隶属者::方法名”,如:String::toUpperCase
方法的隶属者: 静态方法的则是类; 非静态方法则是对象. 隶属者不是接口, 而是定义方法的类或对象.
被引用的方法参数和类型和一定要和接口的方法一致. 而且也要返回值类型也要一致.
方法名的后面没有括号"()"
方法引用可以有多个参数入口,尽管在表达式中省略括号看不到,实际上在接口中会有规定.
各种引用示例
0. 各种函数式接口(便于后面演示)

//1.无返回值的多参接口
@FunctionalInterface
public interface LambdaNoneReturnMultipleParameter {
    void test(int a, int b);
}
//2.无返回值的无参接口
@FunctionalInterface
public interface LambdaNoneReturnNoneParameter {
    void test();
}
//3.无返回值的一参接口
@FunctionalInterface
public interface LambdaNoneReturnSingleParameter {
    void test(int n );
}

//4.有返回值的多参接口
@FunctionalInterface
public interface LambdaSingleReturnMultipleParameter {
    int test(int a, int b);
}
//5.有返回值的无参接口
@FunctionalInterface
public interface LambdaSingleReturnNoneParameter {
    int test();
}
//6.有返回值的一参接口
@FunctionalInterface
public interface LambdaSingleReturnSingleParameter {
    int test(int n);
}

## 函数式接口引用
1.  调用构造方法

```java
     //有参
         @FunctionalInterface
    interface PersonCreator2 {
        Person getPerson(String name, int age);
    }
        PersonCreator2 creator2 = Person::new;
        Person person2 = creator2.getPerson("Fisherman", 18);``
2. 超实例方法引用
语法格式: super::methodName 通过使用super,引用methodName方法的超类版本
同理, 可以捕获this指针. this :: equals 等价于lambda表达式 x -> this.equals(x);
3. 类上实例的方法引用
语法格式:ClassName::methodName
这种方法很不一样, :: 前的类名并不是实例方法的发出者. 真正的发出者是在调用该方法时,作为第一个参数传入方法中.
实现了方法引用的多态性


map、filter的函数式接口定义
```java

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);  // 只有这一个未实现的方法

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t); // 只有这一个未实现的方法

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}





Optional<Integer> result = Stream.of("f", "ba", "hello")
        .map(s -> s.length())
        .filter(l -> l <= 3)
        .max((o1, o2) -> o1-o2);
        
// 还原为函数接口的实现方式
Optional<Integer> result2 = Stream.of("fo", "bar", "hello")
        .map(new Function<String, Integer>() {
          @Override
          public Integer apply(String s) {
            return s.length();
          }
        })
        .filter(new Predicate<Integer>() {
          @Override
          public boolean test(Integer l) {
            return l <= 3;
          }
        })
        .max(new Comparator<Integer>() {
          @Override
          public int compare(Integer o1, Integer o2) {
            return o1 - o2;
          }
        });```

FunctionPredicateComparator 都是函数接口


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值