Java8 函数式接口Predicate、Consumer、Function、Supplier


前言

Java8是 Java 语言的一个重要版本,该版本于2014年3月发布,是自Java5以来最具革命性的版 本,这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Predicate

Predicate

/*
 * 判断一个参数是否符合要求
 */
@FunctionalInterface
public interface Predicate<T> {
	// 用来处理参数T,判断是否符合条件
    boolean test(T var1);
	// 可理解为 条件A && 条件B
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> {
            return this.test(t) && other.test(t);
        };
    }
	// 对当前判断进行"!"操作,即取非操作,可理解为 ! 条件A
    default Predicate<T> negate() {
        return (t) -> {
            return !this.test(t);
        };
    }
	// 对当前判断进行"||"操作,即取或操作,可以理解为 条件A ||条件B
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> {
            return this.test(t) || other.test(t);
        };
    }
	// 对当前操作进行"="操作,即取等操作,可以理解为 A == B
    static <T> Predicate<T> isEqual(Object targetRef) {
        return null == targetRef ? Objects::isNull : (object) -> {
            return targetRef.equals(object);
        };
    }

    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return target.negate();
    }
}

1. boolean test(T var1);

代码如下(示例):

 Predicate<Integer> predicate = x -> x >  0;
 System.out.println(predicate.test(10));//true

2. and(Predicate<? super T> other)

代码如下(示例):

Predicate<Integer> predicate = x -> x >100;
predicate = predicate.and(x -> x % 2 == 0 );
System.out.println(predicate.test(98));// false
System.out.println(predicate.test(102));// true
System.out.println(predicate.test(103));// false

3. negate()

代码如下(示例):

Predicate<Person> personPredicate = x -> x.age > 22;
System.out.println(
                Stream.of(
                        new Person(21,"zhangsan"),
                        new Person(22,"lisi"),
                        new Person(23,"wangwu"),
                        new Person(24,"wangwu"),
                        new Person(25,"lisi"),
                        new Person(26,"zhangsan")
                )
                        .filter(personPredicate.negate())
                        .count()
        );// 4

4. or(Predicate<? super T> other)

代码如下(示例):

 Predicate<Person> predicate =  x -> x.name.equals("lisi");
 predicate = predicate.or(x -> x.age > 25);
 System.out.println(
                Stream.of(
                        new Person(21,"zhangsan"),
                        new Person(22,"lisi"),
                        new Person(23,"wangwu"),
                        new Person(24,"wangwu"),
                        new Person(25,"lisi"),
                        new Person(26,"zhangsan")
                )
                        .filter(predicate)
                        .count()
        );

5. isEqual(Object targetRef)

代码如下(示例):

Person person = new Person(22,"lisi");
Predicate<Person> predicate =  Predicate.isEqual(person);
System.out.println(
                Stream.of(
                        new Person(21,"zhangsan"),
                        new Person(22,"lisi"),
                        new Person(23,"wangwu"),
                        new Person(24,"wangwu"),
                        new Person(22,"lisi"),
                        new Person(26,"zhangsan")
                )
                        .filter(predicate)
                        .count()
        );// 2

二、Consumer

Consumer 数据获取

@FunctionalInterface
public interface Consumer<T> {
    void accept(T var1);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (t) -> {
            this.accept(t);
            after.accept(t);
        };
    }
}

1. accept(T var1)

代码如下(示例):

List<Person> lisiList = new ArrayList<>();
Consumer <Person> consumer  =  x -> {
    if (x.name.equals("lisi")){
        lisiList.add(x);
    }
};
Stream.of(
        new Person(21,"zhangsan"),
        new Person(22,"lisi"),
        new Person(23,"wangwu"),
        new Person(24,"wangwu"),
        new Person(23,"lisi"),
        new Person(26,"lisi"),
        new Person(26,"zhangsan")
).forEach(consumer);

System.out.println(JSON.toJSONString(lisiList));

2. andThen(Consumer<? super T> after)

代码如下(示例):

List<Person> lisiList = new ArrayList<>();
Consumer <Person> consumer  =  x -> {
    if (x.name.equals("lisi")){
        lisiList.add(x);
    }
};

consumer = consumer.andThen(
   x -> lisiList.removeIf(y -> y.age < 23)
);

Stream.of(
        new Person(21,"zhangsan"),
        new Person(22,"lisi"),
        new Person(23,"wangwu"),
        new Person(24,"wangwu"),
        new Person(23,"lisi"),
        new Person(26,"lisi"),
        new Person(26,"zhangsan")
).forEach(consumer);

System.out.println(JSON.toJSONString(lisiList));

三、Function

Function 类型转换

@FunctionalInterface
public interface Function<T, R> {
    R apply(T var1);
	//将Function对象应用到输入的参数上,然后返回计算结果。
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (v) -> {
            return this.apply(before.apply(v));
        };
    }
	//返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (t) -> {
            return after.apply(this.apply(t));
        };
    }
	//返回一个先执行before函数对象apply方法再执行当前函数对象apply方法的函数对象
    static <T> Function<T, T> identity() {
        return (t) -> {
            return t;
        };
    }
}

1. apply(T var1)

代码如下(示例):

Function<Integer, Integer> name = e -> e * 2;
int value = name.apply(3);
System.out.println("andThen value=" + value);// 6

2. compose(Function<? super V, ? extends T> before)

代码如下(示例):

Function<Integer, Integer> name = e -> e * 2;
Function<Integer, Integer> square = e -> e * e;
// 运算逻辑 andThen 先计算前边的,再把得到的参数传入下一次计算
int value = name.andThen(square).apply(3);
System.out.println("andThen value=" + value);// 36

3. andThen(Function<? super R, ? extends V> after)

代码如下(示例):

Function<Integer, Integer> name = e -> e * 2;
Function<Integer, Integer> square = e -> e * e;
// compose 先计算后边的逻辑,再把参数传入前边的运算
int value2 = name.compose(square).apply(3);
System.out.println("compose value2=" + value2);// 18

4. identity()

代码如下(示例):

Function<Integer, Integer> name = e -> e * 2;
Function<Integer, Integer> square = e -> e * e;
Object identity = Function.identity().apply("huohuo");
System.out.println(identity);// huohuo

四、Supplier

Supplier 获取数值

1. get

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

代码如下(示例):

public static void main(String[] args) {
    int[] numbers = {100, 200, 300, 400, 500, -600, -700, -800, -900, -1000};
    int numberMax = arrayMax(
            () -> {
                int max = numbers[0];
                for (int number : numbers) {
                    if (max < number) {
                        max = number;
                    }
                }
                return max;
            }
    );
    System.out.println("数组中的最大值为:" + numberMax);
}

public static Integer arrayMax(Supplier<Integer> s){
    return s.get();
}


总结

函数式接口,个人感觉是未来代码编写必须掌握的技能,平时可以多加查看源码和一些中间件,里面也使用了函数式接口,利用传入参数,把代码整理的简洁易懂。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Java 8 函数式接口是一种拥有单个抽象方法的接口,它可以被隐式地转换为 lambda 表达式。您可以使用 @FunctionalInterface 注解声明一个接口函数式接口。这样做可以帮助编译器检测到您是否正确地在接口中声明了单个抽象方法。 例如: ``` @FunctionalInterface public interface Converter<F, T> { T convert(F from); } ``` 这是一个函数式接口,因为它只有一个抽象方法 `convert()`。您可以使用 lambda 表达式来实现这个接口: ``` Converter<String, Integer> converter = (from) -> Integer.valueOf(from); Integer converted = converter.convert("123"); System.out.println(converted); // 123 ``` 函数式接口使用起来非常方便,因为它们可以被隐式地转换为 lambda 表达式。这使得您可以使用更简洁的代码来实现接口,而无需显式地创建一个类来实现该接口。 ### 回答2: Java 8引入了函数式接口,这是一种只有一个抽象方法的接口函数式接口提供了一种简洁的方式来定义Lambda表达式,Lambda表达式可以作为函数的参数使用。 函数式接口可以通过使用@FunctionalInterface注解来明确标识。这个注解是可选的,但建议使用,因为它可以确保接口只有一个抽象方法,防止不必要的错误。 Java 8提供了一些内置的函数式接口,用于处理常见的函数式编程场景。其中一些常用的函数式接口包括: 1. Predicate(断言):代表一个谓词(布尔类型函数),接受一个参数,返回一个布尔值结果。 2. Consumer(消费者):代表一个消费者(接受一个参数并执行某些操作),接受一个参数,不返回任何结果。 3. Function函数):代表一个函数(接受一个参数并返回一个结果),接受一个参数并返回一个指定类型的结果。 4. Supplier(供应者):代表一个供应者(不接受参数但返回一个结果),不接受任何参数,返回一个指定类型的结果。 这些函数式接口的引入使得Java 8具备了更强大的函数式编程能力,使代码更加简洁和易读。通过结合Lambda表达式和函数式接口,我们可以实现与函数式编程语言类似的编程风格,提高代码的可读性和可维护性。 ### 回答3: Java 8 引入了函数式接口的概念。函数式接口是一个只有一个抽象方法的接口。在 Java 8 之前,我们需要定义一个接口,并在其中添加一个抽象方法,才能够当作 Lambda 表达式的参数进行传递。而在 Java 8 中,我们只需使用 @FunctionalInterface 注解来标注一个接口,就可以将其定义为函数式接口了。这使得我们能够更加简洁地使用 Lambda 表达式。 函数式接口可以用来支持函数式编程,也可以用作 Lambda 表达式的类型。而 Java 8 为我们提供了一些内置的函数式接口,如 FunctionPredicate、ConsumerSupplier 等。这些接口都定义了一些常用的函数式方法,例如 Function 接口中的 apply() 方法,Predicate 接口中的 test() 方法。这些方法可以直接在 Lambda 表达式中使用。 通过使用函数式接口,我们可以更加方便地使用 Lambda 表达式来完成一些常见的操作。例如,我们可以使用 Predicate 接口来过滤集合中的元素,使用 Function 接口来对集合元素进行转换,使用 Consumer 接口来消费集合元素,使用 Supplier 接口来生产对象等等。 总之,Java 8 的函数式接口为我们提供了更加便捷的函数式编程方式。我们可以利用这些接口来定义、传递和使用 Lambda 表达式,从而简化代码,提高开发效率。同时,函数式接口也使得代码更加易读和易维护。然而,我们需要注意函数式接口的设计和使用,以避免出现意外的错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小心仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值