函数式接口介绍

函数式接口是 Java 8 引入的一个重要概念,它在函数式编程和 Lambda 表达式中起着核心作用。函数式接口是指只有一个抽象方法的接口。Java 8 提供了一些内置的函数式接口,如 PredicateFunctionConsumerSupplier 等,同时允许开发者自定义函数式接口。

基本概念

  1. 函数式接口:只有一个抽象方法的接口。
  2. Lambda 表达式:一种简洁的匿名函数,可以用来实现函数式接口。
  3. 方法引用:一种简洁的方式来引用已经存在的方法或构造器。

内置函数式接口

1. Predicate<T>

Predicate 是 Java 8 引入的一个函数式接口,位于 java.util.function 包中。它代表了一个布尔值的函数,通常用于条件判断。Predicate 接口包含一个抽象方法 test,该方法接受一个输入参数并返回一个布尔值。

Predicate 接口的主要方法

  1. test(T t):

    • 参数:T 类型的输入参数。
    • 返回值:boolean 值,表示条件是否满足。
    • 用途:用于测试给定的输入是否满足某个条件。
  2. and(Predicate<? super T> other):

    • 参数:另一个 Predicate 对象。
    • 返回值:一个新的 Predicate 对象,表示两个 Predicate 的逻辑与(AND)。
    • 用途:组合多个条件,只有所有条件都为真时才返回 true
  3. or(Predicate<? super T> other):

    • 参数:另一个 Predicate 对象。
    • 返回值:一个新的 Predicate 对象,表示两个 Predicate 的逻辑或(OR)。
    • 用途:组合多个条件,只要有一个条件为真就返回 true
  4. negate():

    • 参数:无。
    • 返回值:一个新的 Predicate 对象,表示当前 Predicate 的逻辑非(NOT)。
    • 用途:反转当前条件的结果。

示例

基本使用
import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = x -> x % 2 == 0;

        System.out.println(isEven.test(4)); // 输出: true
        System.out.println(isEven.test(3)); // 输出: false
    }
}
组合使用
import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = x -> x % 2 == 0;
        Predicate<Integer> isPositive = x -> x > 0;

        // 组合条件
        Predicate<Integer> isEvenAndPositive = isEven.and(isPositive);
        Predicate<Integer> isEvenOrPositive = isEven.or(isPositive);
        Predicate<Integer> isNotEven = isEven.negate();

        System.out.println(isEvenAndPositive.test(4)); // 输出: true
        System.out.println(isEvenAndPositive.test(-4)); // 输出: false

        System.out.println(isEvenOrPositive.test(4)); // 输出: true
        System.out.println(isEvenOrPositive.test(-3)); // 输出: true

        System.out.println(isNotEven.test(4)); // 输出: false
        System.out.println(isNotEven.test(3)); // 输出: true
    }
}

在集合中的应用

Predicate 常用于集合操作,如过滤集合中的元素。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Predicate<Integer> isEven = x -> x % 2 == 0;

        // 过滤出偶数
        List<Integer> evenNumbers = numbers.stream()
                                           .filter(isEven)
                                           .collect(Collectors.toList());

        System.out.println(evenNumbers); // 输出: [2, 4, 6, 8, 10]
    }
}

总结

Predicate 是一个非常有用的函数式接口,适用于需要进行条件判断的场景。它可以单独使用,也可以通过 andornegate 方法组合成更复杂的条件。在集合操作中,Predicate 与流(Stream)API 结合使用,可以实现高效的过滤和条件判断。

2. Function<T, R>

Function 是 Java 8 引入的一个函数式接口,位于 java.util.function 包中。它代表了一个从一种类型的对象转换为另一种类型的对象的函数。Function 接口包含一个抽象方法 apply,该方法接受一个输入参数并返回一个结果。

Function 接口的主要方法

  1. apply(T t):

    • 参数:T 类型的输入参数。
    • 返回值:R 类型的结果。
    • 用途:用于将输入参数转换为结果。
  2. andThen(Function<? super R,? extends V> after):

    • 参数:另一个 Function 对象。
    • 返回值:一个新的 Function 对象,表示先应用当前 Function,再应用传入的 Function
    • 用途:组合多个 Function,形成一个链式的转换。
  3. compose(Function<? super V,? extends T> before):

    • 参数:另一个 Function 对象。
    • 返回值:一个新的 Function 对象,表示先应用传入的 Function,再应用当前 Function
    • 用途:组合多个 Function,形成一个链式的转换,但顺序与 andThen 相反。

示例

基本使用
import java.util.function.Function;

public class FunctionExample {
    public static void main(String[] args) {
        Function<String, Integer> stringLength = s -> s.length();

        String input = "Hello, World!";
        int length = stringLength.apply(input);

        System.out.println(length); // 输出: 13
    }
}
组合使用
import java.util.function.Function;

public class FunctionExample {
    public static void main(String[] args) {
        Function<String, Integer> stringLength = s -> s.length();
        Function<Integer, Integer> doubleValue = i -> i * 2;

        // 组合函数
        Function<String, Integer> doubleStringLength = stringLength.andThen(doubleValue);

        String input = "Hello, World!";
        int result = doubleStringLength.apply(input);

        System.out.println(result); // 输出: 26
    }
}

在集合中的应用

Function 常用于集合操作,如映射集合中的元素。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.function.Function;

public class FunctionExample {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");

        Function<String, Integer> stringLength = s -> s.length();

        // 映射每个字符串的长度
        List<Integer> lengths = words.stream()
                                     .map(stringLength)
                                     .collect(Collectors.toList());

        System.out.println(lengths); // 输出: [5, 6, 6]
    }
}

总结

Function 是一个非常有用的函数式接口,适用于需要进行类型转换的场景。它可以单独使用,也可以通过 andThencompose 方法组合成更复杂的转换。在集合操作中,Function 与流(Stream)API 结合使用,可以实现高效的映射和转换操作。

3. Consumer<T>

Consumer 是 Java 8 引入的一个函数式接口,位于 java.util.function 包中。它代表了一个接受单个输入参数并且没有返回值的操作。Consumer 接口通常用于表示对数据的消费或处理操作。

Consumer 接口的主要方法

  1. accept(T t):

    • 参数:T 类型的输入参数。
    • 返回值:无。
    • 用途:用于对输入参数进行处理或消费。
  2. andThen(Consumer<? super T> after):

    • 参数:另一个 Consumer 对象。
    • 返回值:一个新的 Consumer 对象,表示先执行当前 Consumer,再执行传入的 Consumer
    • 用途:组合多个 Consumer,形成一个链式的处理操作。

示例

基本使用
import java.util.function.Consumer;

public class ConsumerExample {
    public static void main(String[] args) {
        Consumer<String> printUpperCase = s -> System.out.println(s.toUpperCase());

        String input = "hello, world!";
        printUpperCase.accept(input); // 输出: HELLO, WORLD!
    }
}
组合使用
import java.util.function.Consumer;

public class ConsumerExample {
    public static void main(String[] args) {
        Consumer<String> printUpperCase = s -> System.out.println(s.toUpperCase());
        Consumer<String> printLowerCase = s -> System.out.println(s.toLowerCase());

        // 组合消费者
        Consumer<String> printBothCases = printUpperCase.andThen(printLowerCase);

        String input = "Hello, World!";
        printBothCases.accept(input); // 输出: HELLO, WORLD! 和 hello, world!
    }
}

在集合中的应用

Consumer 常用于集合操作,如遍历集合中的元素并对其进行处理。

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");

        Consumer<String> printUpperCase = s -> System.out.println(s.toUpperCase());

        // 遍历列表并打印每个单词的大写形式
        words.forEach(printUpperCase);
        // 输出:
        // APPLE
        // BANANA
        // CHERRY
    }
}

总结

Consumer 是一个非常有用的函数式接口,适用于需要对数据进行处理或消费的场景。它可以单独使用,也可以通过 andThen 方法组合成更复杂的处理操作。在集合操作中,Consumer 与流(Stream)API 结合使用,可以实现高效的遍历和处理操作。

常见应用场景

  1. 集合遍历:使用 forEach 方法遍历集合并处理每个元素。
  2. 日志记录:将日志记录操作封装为 Consumer,便于在多个地方复用。
  3. 数据处理:对数据进行格式化、转换或其他处理操作。

通过 Consumer,你可以编写更加简洁和模块化的代码,提高代码的可读性和可维护性。

4. Supplier<T>

Supplier 是 Java 8 引入的一个函数式接口,位于 java.util.function 包中。它代表了一个不接受任何参数但返回一个结果的函数。Supplier 接口通常用于表示一个提供某种类型的结果的工厂方法或生成器。

Supplier 接口的主要方法

  1. get():
    • 参数:无。
    • 返回值:T 类型的结果。
    • 用途:用于生成并返回一个结果。

示例

基本使用
import java.util.function.Supplier;

public class SupplierExample {
    public static void main(String[] args) {
        Supplier<String> messageSupplier = () -> "Hello, World!";

        String message = messageSupplier.get();
        System.out.println(message); // 输出: Hello, World!
    }
}
生成随机数
import java.util.Random;
import java.util.function.Supplier;

public class SupplierExample {
    public static void main(String[] args) {
        Supplier<Integer> randomSupplier = () -> new Random().nextInt(100);

        int randomNumber = randomSupplier.get();
        System.out.println(randomNumber); // 输出: 一个 0 到 99 之间的随机整数
    }
}

在集合中的应用

Supplier 可以用于生成集合的初始值或默认值。

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class SupplierExample {
    public static void main(String[] args) {
        Supplier<List<Integer>> listSupplier = ArrayList::new;

        List<Integer> myList = listSupplier.get();
        myList.add(1);
        myList.add(2);
        myList.add(3);

        System.out.println(myList); // 输出: [1, 2, 3]
    }
}

在 Optional 中的应用

Supplier 也常用于 Optional 类中的 orElseGet 方法,用于提供一个默认值生成器。

import java.util.Optional;
import java.util.function.Supplier;

public class SupplierExample {
    public static void main(String[] args) {
        Optional<String> optional = Optional.empty();
        Supplier<String> defaultSupplier = () -> "Default Value";

        String result = optional.orElseGet(defaultSupplier);
        System.out.println(result); // 输出: Default Value
    }
}

总结

Supplier 是一个非常有用的函数式接口,适用于需要生成某种类型的结果的场景。它可以单独使用,也可以与其他功能接口和类结合使用,例如在集合初始化、生成随机数、提供默认值等方面。通过 Supplier,你可以编写更加简洁和模块化的代码,提高代码的可读性和可维护性。

常见应用场景

  1. 生成默认值:在 Optional 中提供默认值生成器。
  2. 集合初始化:生成集合的初始值或默认值。
  3. 随机数生成:生成随机数或随机对象。
  4. 配置文件加载:从配置文件中读取并返回配置值。

通过 Supplier,你可以轻松地创建和管理生成结果的逻辑,使代码更加灵活和高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值