欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于Consumer接口、Predicate接口初使用

程序员文章站 2022-06-19 18:01:39
目录consumer 接口源码直接使用 accept()使用 andthen()predicate 接口源码使用 test()使用 negate()使用 and()使用 or()、isequal()c...

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

从源码中可以得到,consumer 接口是函数式接口,并且这个函数式接口的唯一抽象方法是没有返回值的,也许大家会有疑惑,没有返回值,那这个接口有什么用呢?当然,这个接口不会给我们返回什么值,但是我们可以用来修改传递过来的参数啊,这样比直接修改又多了什么优点呢?额,自己挖坑?我也说不上来多了什么优点,我还很弱,不过我喜欢这种编程方式。

直接使用 accept()

举个例子,假如用户的 name 为 null,那么就可以给他设置一个默认的 name ,想不到好的例子,感觉这个例子不是很合理,但是意思差不多。

user.java:

package entity;
public class user {
    // 用户默认名字
    public static final string  default_name = "kaven";
    // 用户的年龄
    private int age;
    // 用户的名字
    private string name;
    public int getage() {
        return age;
    }
    public void setage(int age) {
        this.age = age;
    }
    public string getname() {
        return name;
    }
    public void setname(string name) {
        this.name = name;
    }
}

testconsumer.java:

package test;
import entity.user;
import java.util.function.consumer;
public class testconsumer{
    public static void main(string[] args){
        consumer<user> consumer = user -> user.setname(user.default_name);
        user user = new user();
        if(user.getname() == null) consumer.accept(user);
        system.out.println(user.getname());
    }
}

输出:kaven

使用 andthen()

从源码可以得到,this 进行 accept() 后,after 再进行 accept(),相当于进行了两次 accept() 。

    default consumer<t> andthen(consumer<? super t> after) {
        objects.requirenonnull(after);
        return (t t) -> { accept(t); after.accept(t); };
    }

下面以小学成绩单为例,假设小学成绩单是由两门单科成绩(语文、数学)和总分组成,当我们需要修改其中一门成绩的时候,我们是不是也需要修改总分呢?这是肯定的啊。当然,这个例子也不是很合理。

grade.java:

package entity;
public class grade {
    // 语文成绩
    private int chinese_language;
    // 英语成绩
    private int english;
    // 总分
    private int total_score;
    public grade(int chinese_language, int english){
        this.chinese_language = chinese_language;
        this.english = english;
        this.total_score = chinese_language + english;
    }
    public int getchinese_language() {
        return chinese_language;
    }
    public void setchinese_language(int chinese_language) {
        this.chinese_language = chinese_language;
    }
    public int getenglish() {
        return english;
    }
    public void setenglish(int english) {
        this.english = english;
    }
    public int gettotal_score() {
        return this.total_score;
    }
    public void settotal_score() {
        this.total_score = this.chinese_language + this.english;
    }
}

testconsumerandthen.java:

package test;
import entity.grade;
import java.util.function.consumer;
public class testconsumerandthen {
    public static void main(string[] args){
        consumer<grade> total_score = grade -> {
            grade.settotal_score();
        };
        consumer<grade> english = grade -> {
            grade.setenglish(80);
        };
        grade grade = new grade(80,70);
        system.out.printf("英语成绩为:%d\n",grade.getenglish());
        system.out.printf("总分为:%d\n",grade.gettotal_score());
        english.andthen(total_score).accept(grade);
        system.out.println("修改英语成绩后---------------");
        system.out.printf("英语成绩为:%d\n",grade.getenglish());
        system.out.printf("总分为:%d\n",grade.gettotal_score());
    }
}

输出:

英语成绩为:70
总分为:150
修改英语成绩后---------------
英语成绩为:80
总分为:160

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

predicate 接口也是函数式接口,调用接口的 test 方法会返回一个布尔类型的值,其实从 predicate 接口的源码中也可以看出来,这个接口的用处是什么。

以我的理解,是可以用来判断传递过来的参数是否匹配一些条件。

使用 test()

我们还是使用 consumer 接口的例子,当用户的 name 为 null 时,给用户设置默认的 name。

我们可以用 predicate 接口来判断用户的 name 是否为空,可能看起来比直接比较麻烦一点。

testpredicate.java:

package test;
import entity.user;
import java.util.function.consumer;
import java.util.function.predicate;
public class testpredicate {
    public static void main(string[] args){
        consumer<user> consumer = user -> user.setname(user.default_name);
        predicate<user> predicate = user -> {
            return user.getname() == null ;
        };
        user user = new user();
        if(predicate.test(user)) consumer.accept(user);
        system.out.println(user.getname());
    }
}

输出:kaven

一样的效果。

使用 negate()

从源码中可以得到,negate() 是返回一个对 test() 的结果取一次反的 predicate 实例。

default predicate<t> negate() {
        return (t) -> !test(t);
}

也可以这样用,负负得正不是吗。

if(!predicate.negate().test(user)) consumer.accept(user);

使用 and()

and() 返回一个对两个 test() 以 && 的方式的 predicate 实例。

default predicate<t> and(predicate<? super t> other) {
        objects.requirenonnull(other);
        return (t) -> test(t) && other.test(t);
}

在 user.java 里面加一个用户默认年龄属性。

 // 用户默认年龄
    public static final int default_age = 20;

当用户年龄不符合情况并且名字为空时,就重新设置用户的年龄和名字。

testpredicate.java:

package test;
import entity.user;
import java.util.function.consumer;
import java.util.function.predicate;
public class testpredicate {
    public static void main(string[] args){
        consumer<user> consumer = user -> user.setname(user.default_name);
        consumer<user> consumer_age = user -> user.setage(user.default_age);
        predicate<user> predicate = user -> {
            return user.getname() == null ;
        };
        predicate<user> predicate_age = user -> {
            int age = user.getage();
            return  (age <= 0 || age >=150);
        };
        user user = new user();
        if(predicate.and(predicate_age).test(user)) consumer.andthen(consumer_age).accept(user);
        system.out.println(user.getname());
        system.out.println(user.getage());
    }
}

输出:

kaven
20

predicate接口还有两个方法:

  • or()

or() 方法应该很容易理解,or() 返回一个对两个 test() 以 || 的方式的 predicate 实例。

default predicate<t> or(predicate<? super t> other) {
        objects.requirenonnull(other);
        return (t) -> test(t) || other.test(t);
}
  • isequal()

接口的静态方法,看源码也很容易理解,生成一个判断是否与 targetref equal的 predicate 实例。targetref 不为 null 时,如果 targetref 这个实例的类中没有重载 object 类的 equals() 方法或者 targetref 这个实例本身就是 object 类的实例,就会使用 object 类的 equals() 进行判断,就只会判断传递过来的参数的引用是否与 targetref 一样,和 == 相同。

static <t> predicate<t> isequal(object targetref) {
        return (null == targetref)
                ? objects::isnull
                : object -> targetref.equals(object);
}

从 object 类的源码也很容易看出来,equals() 就是直接使用的 == 进行判断的。

public boolean equals(object obj) {
     return (this == obj);
}

要想使用自己的 equals() 进行判断,就在 targetref 实例的类中重写 equals() 方法。

比如在 user.java 中重写 equals():

    @override
    public boolean equals(object obj) {
        if(obj == null) return false;
        else{
            if(obj instanceof user){
                user user = (user) obj;
                // string 类已经重载了 equals()
                if(this.name.equals((user).name) && this.age == user.age) return true;
                else return false;
            }
            else return false;
        }
    }

使用 or()、isequal()

package test;
import entity.user;
import java.util.function.consumer;
import java.util.function.predicate;
public class testpredicate {
    public static void main(string[] args){
        consumer<user> consumer = user -> user.setname(user.default_name);
        consumer<user> consumer_age = user -> user.setage(user.default_age);
        predicate<user> predicate = user -> {
            return user.getname() == null ;
        };
        predicate<user> predicate_age = user -> {
            int age = user.getage();
            return  (age <= 0 || age >=150);
        };
        user user = new user();
        user.setage(21);
        if(predicate.or(predicate_age).test(user)) consumer.andthen(consumer_age).accept(user);
//        if(predicate.and(predicate_age).test(user)) consumer.andthen(consumer_age).accept(user);
//        if(!predicate.negate().test(user)) consumer.accept(user);
//        if(predicate.test(user)) consumer.accept(user);
        user user_equal = new user(user.default_age , user.default_name);
        system.out.println(predicate.isequal(user).test(user_equal));
        system.out.println(user.equals(user_equal));
        system.out.println(user.getname());
        system.out.println(user.getage());
    }
}

输出:

true
true
kaven
20

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。