函数式接口不会用?看这篇文章就够了

目录

一. 函数式接口简介

1、什么是函数式接口?

2. 为什么要使用函数式接口?

3. 函数式接口定义

二. 常用函数式接口

Consumer 接口

Supplier 接口

Function 接口

Predicate 接口

三、定义自己的函数式接口


一. 函数式接口简介

1、什么是函数式接口?

如果在Java的接口中,有且只有一个抽象方法,那么这种接口就是函数式接口。函数式接口是使用Lambda表达式的前提条件。

2. 为什么要使用函数式接口?

在Java中不支持将函数作为一个数据,也就不能将函数作为方法的参数进行传递。因此给函数外加一层接口的声明,相当于为其穿上一件漂亮的外衣包装起来。如果需要将函数作为方法传递时,就可以传递函数所在接口的实现类对象,来间接的传递方法内容了。

3. 函数式接口定义

我们可以使用@FunctionalInterface注解来检查一个接口是否是一个函数式接口。放在接口定义的上方,如果接口是函数式接口,编译通过;如果不是,则编译失败。

二. 常用函数式接口

Java8中提供了一些常用的函数式接口,在使用类似功能的时候,不需要额外定义接口,直接使用jdk8中提供的即可。这里介绍如下4种:

  • Consumer 接口
  • Supplier 接口
  • Function 接口
  • Predicate 接口

  • Consumer 接口

  • 用于表示接受一个参数且无返回值的操作。它只有一个抽象方法 accept(T t),用于对给定的参数执行操作。例如,在处理集合时,可以使用 Consumer 接口来对每个元素执行某种操作,如打印、修改等。

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

 使用实例 :

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 遍历打印
numbers.forEach(value -> System.out.println("Hello, " + value));

// 迭代器
public interface Iterable<T> {
   
    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
}
  • Supplier 接口

  • 用于表示无参数且返回一个结果的操作。它只有一个抽象方法 get(),用于获取结果。Supplier 接口常用于需要生成值而不需要任何输入参数的场景。

package java.util.function;

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

使用示例:

List<Integer> list1 = useSupplier(5, () -> (int) (Math.random() * 10 + 1));

// 返回n个满足某个规律的数
public static List<Integer> useSupplier(int count, Supplier<Integer> sup){
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            Integer integer = sup.get();
            list.add(integer);
        }
        return list;
    }
  • Function 接口

  • 表示接受一个参数并返回结果的函数。它有一个抽象方法 apply(T t),用于将输入参数应用到函数上并返回结果。Function 接口是函数式编程中的核心概念之一,允许将数据转换为另一种形式或执行特定的计算逻辑。

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

使用示例:

List<Person> persons = new ArrayList<>();
        List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());

static class Person {
        private String name;
        private int age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }
  • Predicate 接口

  • 表示一个参数的谓词(布尔值函数)。它有一个抽象方法 test(T t),用于评估给定的参数是否满足某个条件并返回布尔值。Predicate 接口常用于过滤、判断等场景,如检查集合中的元素是否满足某个条件。

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

使用示例:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream().filter((n) -> n % 2 == 0).forEach(System.out::println);

三、定义自己的函数式接口

package com.cjian.functionalinterface;

/**
 * @Author: cjian
 * @Date: 2024/6/7 17:16
 * @Des:
 */

@FunctionalInterface
public interface MyFunctionInterface {
    void out(String msg);
}

测试:

 static void testMyFunctionInterface(String msg , MyFunctionInterface myFunctionInterface){
        myFunctionInterface.out(msg);
 }

testMyFunctionInterface("Hello cj!", msg -> System.out.println(msg));

可以看到我们可以将函数作为一个参数传递给方法。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值