网站首页 > 精选教程 正文
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数。
为什么java中可以使用函数式编程
Java本身是面向对象的程序设计语言,要想在Java中使用函数式编程的特性,首先需要支持函数式编程。编程语言中需要有结构来表示函数是支持函数式编程的一大特征。在Java中使用接口来表示函数,Python中有map和reduce等。
在java中函数的定义
函数式编程可以提高我们的开发效率(什么是函数式编程),那么在Java中怎么定义和使用这样一个特性呢?
上面说明了Java中是通过接口定义函数的,所以如果接口中添加了@FunctionalInterface注解,则这个接口是可以用做函数式编程的。
当然并不是所有接口都可以添加这个注解的,@FunctionalInterface注解有几个限制条件,分别是:
- 接口有且仅有一个抽象方法
- 允许定义静态方法
- 允许定义默认方法
直到Java8,Java才提供了内置标准API来表示函数,也就是java.util.function包。Function<T, R>表示接受一个参数的函数,输入类型为T,输出类型为R。
下面以java.util.function包下的Function接口的源码为例:
@FunctionalInterface
public interface Function<T, R> {
// 有且仅有一个抽象方法
R apply(T t);
// 默认方法1
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
// 默认方法2
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;
}
}
除了 Function ,Java 标准库还提供了几种特殊类型的函数:
- Consumer:接受一个输入,没有输出。抽象方法为 void accept(T t)。
- Supplier:没有输入,一个输出。抽象方法为 T get()。
- Predicate:接受一个输入,输出为 boolean 类型。抽象方法为 boolean test(T t)。
- UnaryOperator:接受一个输入,输出的类型与输入相同,相当于 Function<T, T>。
- BinaryOperator:接受两个类型相同的输入,输出的类型与输入相同,相当于 BiFunction<T,T,T>。
- BiPredicate<T, U>:接受两个输入,输出为 boolean 类型。抽象方法为 boolean test(T t, U u)。
另外如果一个接口满足上面的`@FunctionalInterface`注解的要求可以不需要显示的添加`@FunctionalInterface`注解。
不过通常还是主动添加`@FunctionalInterface`注解,添加注解后如果在当前接口再添加抽象方法时,编辑器会提示不允许添加。
如何自定义函数接口
根据@FunctionalInterface注解的要求可以实现自定义函数接口。
// 自定义函数接口
@FunctionalInterface
public interface CustomAddFunc<T, R> {
R add(T t);
}
在Java中函数的使用
因为函数式编程的特点是允许把函数本身作为参数传入另一个函数,所以方法的参数含有上面Java标准库或者自定义的函数类型参数时,就是定义了一个函数式编程的方法了。
带函数参数的方法定义
下面以java.util.stream包下的Stream接口部分源码为例:
// Stream接口部分源码
public interface Stream<T> extends BaseStream<T, Stream<T>> {
Stream<T> filter(Predicate<? super T> predicate);
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
}
filter和map方法都有一个Java标准库中特殊类型的函数参数。
`Function`接受一个参数的函数,输入类型为 T,输出类型为 R。
`Predicate`接受一个输入,输出为 boolean 类型。
带函数参数的方法使用
// 通过匿名内部类的方式实现函数接口
int sum = Arrays.stream(new int[]{1, 2, 3}).map(new IntUnaryOperator() {
@Override
public int applyAsInt(int operand) {
return operand + 1;
}
}).sum();
System.out.println(sum); // 输出 9
优雅的使用带函数参数的方法
Java8提供了lambda表达式,是创建匿名内部类的语法糖(syntax sugar)。所以上面的使用方式可以优化成更短的代码
int l = Arrays.stream(new int[]{1, 2, 3}).map(v -> v + 1).sum();
System.out.println(l);
结合lambda表达式使用函数式编程可以很大程度地减少不必要的代码,达到提高开发效率的目的,而且在表达上也更清晰。
- 上一篇: Java的函数式编程(java函数式编程 豆瓣)
- 下一篇: 「JAVA8」- 函数式接口看这篇就够了
猜你喜欢
- 2025-02-03 Java 的函数式接口(必懂知识点!)(java中函数)
- 2025-02-03 [Java] 函数式编程相关概念 - 笔记2
- 2025-02-03 一、java函数式编程概念(java是函数式编程语言)
- 2025-02-03 「Java 进阶」--Lambda & 函数式编程
- 2025-02-03 Java 函数式编程:开启高效编程之旅
- 2025-02-03 Java开发「函数式编程」——Lambda表达式
- 2025-02-03 Java开发知识点:如何理解Java函数式编程?
- 2025-02-03 「JAVA8」- 函数式接口看这篇就够了
- 2025-02-03 Java的函数式编程(java函数式编程 豆瓣)
- 2025-02-03 java 函数式编程(Java 函数式编程 异常处理)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)