目录
  • consumer 接口
    • 源码
    • 直接使用 accept()
    • 使用 andthen()
  • predicate 接口
    • 源码
    • 使用 test()
    • 使用 negate()
    • 使用 and()
    • 使用 or()、isequal()

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

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