阿里妹导读:Java是面向对象的语言,无法直接调用一个函数。Java 8开始,引入了函数式编程接口与Lambda表达式,便于开发者写出更少更优雅的代码。什么是函数式编程?函数式编程的特点是什么?本文通过代码实例,从Stream类、Lambda表达式和函数接口这三个语法概念来分享Java对函数式编程的支持。
文末福利:Java微服务沙箱体验挑战。
Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("do something...");}};
// 一行即可Runnable runnable = () -> System.out.println("do something...");
// 有状态函数: 执行结果依赖b的值是多少,即便入参相同,// 多次执行函数,函数的返回值有可能不同,因为b值有可能不同。int b;int increase(int a) {return a + b;}// 无状态函数:执行结果不依赖任何外部变量值// 只要入参相同,不管执行多少次,函数的返回值就相同int increase(int a, int b) {return a + b;}
public class Demo {public static void main(String[] args) {Optional<Integer> result = Stream.of("a", "be", "hello").map(s -> s.length()).filter(l -> l <= 3).max((o1, o2) -> o1-o2);System.out.println(result.get()); // 输出2}}
add(multiply(subtract(3,1),2),5);
subtract(3,1).multiply(2).add(5);
public class Demo {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}}
// Stream类中map函数的定义:public interface Stream<T> extends BaseStream<T, Stream<T>> {<R> Stream<R> map(Function<? super T, ? extends R> mapper);//...省略其他函数...}// Stream类中map的使用方法示例:Stream.of("fo", "bar", "hello").map(new Function<String, Integer>() {public Integer apply(String s) {return s.length();}});// 用Lambda表达式简化后的写法:Stream.of("fo", "bar", "hello").map(s -> s.length());
(a, b) -> { 语句1;语句2;...; return 输出; } //a,b是输入参数
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>() {public Integer apply(String s) {return s.length();}}).filter(new Predicate<Integer>() {public boolean test(Integer l) {return l <= 3;}}).max(new Comparator<Integer>() {public int compare(Integer o1, Integer o2) {return o1 - o2;}});
Lambda就是为了优化匿名内部类而生,Lambda要比匿名类简洁的多得多。
Lambda仅适用于函数式接口,匿名类不受限。
即匿名类中的this是“匿名类对象”本身;Lambda表达式中的this是指“调用Lambda表达式的对象”。
一个函数式接口只有一个抽象方法(single abstract method);
Object类中的public abstract method不会被视为单一的抽象方法;
函数式接口可以有默认方法和静态方法;
函数式接口可以用@FunctionalInterface注解进行修饰。
public interface Comparator<T> {/*** single abstract method* @since 1.8*/int compare(T o1, T o2);/*** Object类中的public abstract method* @since 1.8*/boolean equals(Object obj);/*** 默认方法* @since 1.8*/default Comparator<T> reversed() {return Collections.reverseOrder(this);}/*** 静态方法* @since 1.8*/public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {return Collections.reverseOrder();}//省略...}
规规矩矩的写一个实现了Comparator接口的Java类去封装排序逻辑。若业务需要多种排序方式,那就得写多个类提供多种实现,而这些实现往往只需使用一次。
另外一种聪明一些的做法无外乎就是在需要的地方搞个匿名内部类,比如:
public class Test {public static void main(String args[]) {List<Person> persons = new ArrayList<Person>();Collections.sort(persons, new Comparator<Person>(){public int compare(Person o1, Person o2) {return Integer.compareTo(o1.getAge(), o2.getAge());}});}}
Comparator<Person> comparator = (p1, p2) -> Integer.compareTo(p1.getAge(), p2.getAge());
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;}}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);}}
Java微服务沙箱体验挑战
10分钟搭建一个Task Manager任务管理器
使用阿里云Java工程脚手架一键生成你的代码框架,并通过场景体验,学习使用微服务构建一套简单的分布式应用,最终实现一款代办事项管理软件。完成4个实验,通过Java基础和体验相关知识自测还可领取start.aliyun.com x IntelliJ联名小礼物!
点击“阅读原文”,立即去挑战吧!