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

网友投稿 216 2022-11-13

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

目录Consumer 接口源码直接使用 accept()使用 andThen()Predicate 接口源码使用 test()使用 negate()使用 and()使用 or()、isEqual()

Consumer 接口

源码

package java.util.function;

import java.util.Objects;

@FunctionalInterface

public interface Consumer {

void accept(T t);

default Consumer 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;

}

}

http://

testConsumer.java:

package test;

import entity.User;

import java.util.function.Consumer;

public class testConsumer{

public static void main(String[] args){

Consumer 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 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.chineshttp://e_language + this.english;

}

}

testConsumehttp://rAndThen.java:

package test;

import entity.Grade;

import java.util.function.Consumer;

public class testConsumerAndThen {

public static void main(String[] args){

Consumer total_score = grade -> {

grade.setTotal_score();

};

Consumer 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 {

boolean test(T t);

default Predicate and(Predicate super T> other) {

Objects.requireNonNull(other);

return (t) -> test(t) && other.test(t);

}

default Predicate negate() {

return (t) -> !test(t);

}

default Predicate or(Predicate super T> other) {

Objects.requireNonNull(other);

return (t) -> test(t) || other.test(t);

}

static Predicate 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 consumer = user -> user.setName(User.DEFAULT_NAME);

Predicate 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 negate() {

return (t) -> !test(t);

}

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

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

使用 and()

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

default Predicate 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 consumer = user -> user.setName(User.DEFAULT_NAME);

Consumer consumer_age = user -> user.setAge(User.DEFAULT_AGE);

Predicate predicate = user -> {

return user.getName() == null ;

};

Predicate 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 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 Predicate 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 consumer = user -> user.setName(User.DEFAULT_NAME);

Consumer consumer_age = user -> user.setAge(User.DEFAULT_AGE);

Predicate predicate = user -> {

return user.getName() == null ;

};

Predicate 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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Type-C实现逐步普及 魅族又一次领先一小步
下一篇:云计算每周之“红黑榜”
相关文章

 发表评论

暂时没有评论,来抢沙发吧~