基于Consumer接口、Predicate接口初使用
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
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
上一篇: 进击的中古圈,如何提升“信任感“?
推荐阅读
-
Java Predicate及Consumer接口函数代码实现解析
-
Asp.Net Core 使用Quartz基于界面画接口管理做定时任务
-
Java常用函数式接口--Consumer接口andThen()方法使用案例(二)
-
基于Consumer接口、Predicate接口初使用
-
函数式接口的用途(Function、Predicate、Consumer、Supplier)
-
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
-
如何使用Python基于接口编程的方法实现
-
Java Predicate及Consumer接口函数代码实现解析
-
基于HBase Thrift接口的一些使用问题及相关注意事项的详解_php技巧
-
基于HBase Thrift接口的一些使用问题及相关注意事项的详解