我的编程空间,编程开发者的网络收藏夹
学习永远不晚

基于Consumer接口、Predicate接口初使用是怎样的

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

基于Consumer接口、Predicate接口初使用是怎样的

这篇文章将为大家详细讲解有关基于Consumer接口、Predicate接口初使用是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

Consumer 接口

源码

package java.util.function;import java.util.Objects;@FunctionalInterfacepublic 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;@FunctionalInterfacepublic 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

关于基于Consumer接口、Predicate接口初使用是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

基于Consumer接口、Predicate接口初使用是怎样的

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

基于Consumer接口、Predicate接口初使用是怎样的

这篇文章将为大家详细讲解有关基于Consumer接口、Predicate接口初使用是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Consumer 接口源码package java.u
2023-06-22

SpringCloud基于Feign的可编程式接口怎么调用

今天小编给大家分享一下SpringCloud基于Feign的可编程式接口怎么调用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧
2023-06-30

微信域名拦截检测的API接口以及官方的调用文档是怎样的

本篇文章给大家分享的是有关微信域名拦截检测的API接口以及官方的调用文档是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。背景由于微信限制比较严格,域名很容易会被判定一下几
2023-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录