JAVA 8 Function

本文深入解析Java8中的函数式接口,包括Supplier、Consumer、Predicate和Function四大核心接口的功能与应用场景,以及如何利用这些接口提升代码效率。

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

1.什么是函数式接口?

首先,它是一个接口,所以必须满足接口最基本的定义。但它是一个特殊的接口:SAM类型的接口(Single Abstract Method)。可以在调用时,使用一个lambda表达式作为参数。所有函数式接口都在这个包:java.util.function。

定义要求:

  • 只能有一个抽象方法需要被实现。
  • 可以有从Object继承过来的抽象方法,因为所有类的最终父类都是Object。
  • 接口中唯一抽象方法的命名并不重要,因为函数式接口就是对某一行为进行抽象,主要目的就是支持Lambda表达式。

Java8还提供了@FunctionalInterface注解来帮助我们标识函数式接口。所以Java8后上面那些接口都被打上了这个标记。

2.四大核心函数式接口

名称一元接口二元接口方法说明
一般函数FunctionBiFunctionapply输入T,输出R
算子函数UnaryOperatorBinaryOperatorapply输入输出同类型
谓词函数PredicateBiPredicatetest输出boolean
消费者ConsumerBiConsumeraccept无返回值
生产者Supplier-get无参数,只有返回值

3.详细说明

3.1 Supplier

这是一个生产者,该接口就一个抽象方法get方法,不用传入任何参数,直接返回一个泛型T的实例.就如同无参构造一样.,源码如下:

package java.util.function;
 
@FunctionalInterface
public interface Supplier<T> {
    T get();
}

示例如下:

public static void testSupplier()
{
    Supplier<String> str = String::new;

    String a = str.get();
    String b = str.get();

    System.out.println(a == b);
}

运行结果:

false

3.2 Consumer

这是一个消费者,接收一个T类型的参数,不返回值,该类的源码如下:

package java.util.function;

import java.util.Objects;

@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); };
    }
}

该函数式接口有两个方法:

  • accept:该函数式接口的唯一的抽象方法,接收一个参数,没有返回值.
  • andThen:在执行完调用者方法后再执行传入参数的方法.
    示例如下:
public static void testConsumer()
{
    Consumer<Integer> consumer1 = x -> System.out.println(x * 2);
    Consumer<Integer> consumer2 = x -> System.out.println(x * 5);

    consumer1.andThen(consumer2).accept(10);
}

运行结果:

20
50

3.3 Predicate

Predicate是个断言式接口其参数是<T,boolean>,也就是给一个参数T,返回boolean类型的结果。源码如下:

package java.util.function;

import java.util.Objects;

@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);
    }
    
    @SuppressWarnings("unchecked")
    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return (Predicate<T>)target.negate();
    }
}

Predicate提供一个test方法,三个默认方法and、or、negate,两个静态方法isEquals、not

  • test:函数式接口断言,给一个参数T,返回boolean类型的结果。
  • and:接收一个Predicate类型,装传入的条件和当前条件以并且的关系过滤数据。
  • or:or方法接收一个Predicate类型,将传入的条件和当前的条件以或者的关系过滤数据。
  • negate:将当前条件取反。
  • isEquals:通过传入对象的equals方法进行判断。
  • not:将传入条件取反。

示例如下:

public static void testPredicate()
{
    //无限流:1,2,3,4,5...
    Stream<Integer> stream = Stream.iterate(1, i -> i + 1);

    Predicate<Integer> p1 = i -> i > 4;//大于4
    Predicate<Integer> p2 = i -> i < 8;//小于8
    Predicate<Integer> p3 = i -> i % 2 == 0;//偶数

    //取无限流前10条数据,大于4,并且小于8,并且非偶数,或者等于1
    stream.limit(10).filter(p1.and(p2).and(p3.negate()).or(Predicate.isEqual(1))).forEach(System.out::println);
}

运行结果:

1
5
7

3.4 Function

接收一个T类型的参数,返回一个R类型的结果,源码如下:

package java.util.function;

import java.util.Objects;

@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;
    }
}

Function提供一个apply方法和三个默认实现方法compose、andThen和identity

  • apply:函数式接口方法,输入T,输出R。
  • compose:compose接收一个Function参数,先执行传入的逻辑,再执行当前的逻辑。
  • andThen:andThen接收一个Function参数,先执行当前的逻辑,再执行传入的逻辑。
  • identity:方便方法的连缀,返回当前对象。

示例如下:

public static void testFunction()
{
    Function<Integer, Integer> func1 = i -> i + i;
    Function<Integer, Integer> func2 = i -> i * i;

    System.out.println(func1.compose(func2).apply(3));
    System.out.println(func1.andThen(func2).apply(3));
}

运行结果:

18
36

4.架构体系

  • 一般函数: 输入T,输出R
    • Function: 接收T对象,返回R对象
      • IntFunction
        • IntToDoubleFunction
        • IntToLongFunction
      • LongFunction
        • LongToDoubleFunction
        • LongToIntFunction
      • DoubleFunction
        • DoubleToIntFunction
        • DoubleToLongFunction
      • ToDoubleFunction
      • ToIntFunction
      • ToLongFunction
      • UnaryOperator: 接收T对象,返回T对象,返回类型与传入参数类型相同
        • IntUnaryOperator
        • LongUnaryOperator
        • DoubleUnaryOperator
    • BiFunction:传入一个参数,返回一个结果
      • ToDoubleBiFunction
      • ToIntBiFunction
      • ToLongBiFunction
      • BinaryOperator:接收两个T对象,返回T对象,返回类型与传入的两个参数类型相同
        • IntBinaryOperator
        • LongBinaryOperator
        • DoubleOperator
  • 谓词函数: 输出boolean
    • Predicate:接收T对象并返回boolean
      • IntPredicate
      • LongPredicate
      • DoublePredicate
    • BiPredicate:
  • 消费者: 无返回值
    • Consumer:接收T对象,不返回值
      • IntConsumer
      • LongConsumer
      • DoubleConsumer
    • BiConsumer:
      • ObjIntConsumer
      • ObjLongConsumer
      • ObjDoubleConsumer
  • 供应者: 无参数,只有返回值
    • Supplier:提供T对象(例如工厂),不接收值
      • IntSupplier
      • LongSupplier
      • DoubleSupplier
      • BooleanSupplier
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值