Java 函数式编程 浅结

本文深入探讨Java函数式编程核心概念,包括函数式接口、方法引用、Lambda表达式及其实现技巧。通过具体代码示例,解析ArrayList的forEach方法与方法引用结合使用,展示Consumer接口的实际应用。同时,介绍了Optional类和Stream API,详解其常用操作方法,如forEach、map、filter等,以及如何利用Collectors收集流元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考链接 Java 函数式编程

 

基本概念

函数式接口:只含有一个抽象方法的接口。

@FunctionalInterface 接口声明:表示这是一个函数式接口,修改接口时编译器将会检查是否符合函数式接口规则。

方法引用: 形如构造器方法引用 Customer::new  或者普通方法  customer::pay (前面Customer是Java类,后者customer是实例),这种写法被称为方法引用。 

方法引用遵循一般方法调用规则(构造器方法引用固定为::new),如 静态方法可以直接经由类名调出,普通方法须由实例调出。

Lambda 表达式:形如 (p1, p2)-> { expression } 的code形式被称为 Lambda 表达式,这种形式是对函数式接口的快速实现。

最繁琐写法:  (Class1 p1, Class2 p2)-> { expression }

省略类型写法:(p1, p2)-> { expression }

一个参数时省略小括号写法  p -> { expression }

实现方法只有一句时去掉花括号: p -> expression 

 

代码分析

来看一段代码

List<String> list = new ArrayList<>();

list.forEach(System.out::println);

焦点在 System.out::println ,原貌是这样的:

(String s) -> System.out.print(s)

分析:

ArrayList  forEach 方法源码:

default void forEach(Consumer<? super T> action) {

        Objects.requireNonNull(action);

        for (T t : this) {

            action.accept(t);

        }

}

看看 Consumer 接口定义:

@FunctionalInterface

public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {

        Objects.requireNonNull(after);

        return (T t) -> { accept(t); after.accept(t); };

    }

}

看出没,Consumer 接口是一个函数式接口,唯一抽象方法 accept 接受一个任意对象,返回为空,而表达式

(String s) -> System.out.print(s)

就是对这个接口的实现,回到 forEach 方法,看到 for 循环中 调用此方法:

 action.accept(t);

 

介绍两个有意思的小工具

● optional

java.util.Optional 一个容器对象,用于容纳非空对象。常见于 JPA 查询 (如默认方法 findById)中。这里有一些有趣的方法:

- isPresent()  返回boolean,判断目标对象是否为空。

- get()  如果目标对象存在,则返回该对象,否则报错。

- ifPresent(Consumer<? super T> consumer)  如果目标对象存在,则执行传入的方法。

- empty()  返回一个空的optional对象

- 更多详情参见官方手册  Java 8 Optional

● stream

Java 8 特性之一,流处理技术,stream对象代表了来自某个源的对象的序列。生成方法:

- collection.stream()  产生最常见的连续流

- collection.parallelStream()  返回支持多核处理的并行流

stream对象一些有意思的处理方法:

- forEach(Consumer<? super T> action)  遍历流中的数据

- map(Function<? super T, ? extends R> mapper)  进行唯一遍历,相同元素只遍历一次

- filter(Predicate<? super T> predicate)  返回符合过滤条件的元素组成的流

- limit(long maxSize)  限制流的大小

- sorted(Comparator<? super T> comparator)  对元素进行排序,不输入排序方法则使用默认排序

结束流:

- collect(Collector collector)  使用 java.util.stream.Collectors 可以快速收集元素,如 toList 、toSet 等,例:

ArrayList<Integer> numbers = new ArrayList<>();

numbers.add(1);

List<Integer> collect = numbers.stream().map(n -> {

    System.out.println(n);

    return n;

}).collect(Collectors.toList());

统计:

- mapToInt(n -> n).summaryStatistics()  由普通流转化为整型流,并得到统计数据,例:

ArrayList<Integer> numbers = new ArrayList<>();

numbers.add(1);

IntSummaryStatistics statistics = numbers.stream().mapToInt(n -> n).summaryStatistics();

System.out.println(statistics.getMax());  // 最大值

System.out.println(statistics.getSum());  // 总和

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值