文章目录
写在前面
java.util.function.Consumer 接口,一般用它来消费一个数据, 其数据类型由泛型决定。
1、 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); };
}
}
1.1、@FunctionalInterface注解
每个函数式接口定义的时候必须加@FunctionalInterface注解,
它的作用:用来提示该接口是一个函数式接口,只能一个抽象方法(可以包含多个默认方法或多个 static 方法),如下例:
静态方法和默认方法的区别:静态方法实现类无法继承,default方法实现类可以继承。
@FunctionalInterface
public interface FunInterface {
static void print() {
System.out.println("可以有多个static方法");
}
default void show() {
System.out.println("可以有多个默认方法");
}
void test(); // 只定义一个抽象方法
}
@FunctionalInterface 注解主要是帮助程序员避免一些低级错误,如上 FunInterface 接口中再增加一个抽象方法 test1() 就会报出异常
不写 @FunctionalInterface 也可以,如下两接口:
接口1:
@FunctionalInterface
interface A{
int add(int a , int b);
}
接口2:
interface A{
int add(int a , int b);
}
1.2、void accept(T t)
accept()方法用来消费传进来的数据t
1.3、default Consumer andThen(Consumer<? super T> after)
- 首先这是一个默认实现的方法(不用再实现,可以直接调用)
- 传入参数是Consumer类型的
- 返回参数是Consumer类型的
Objects.requireNonNull(after);
判断传入参数after不能为null
(T t) -> { accept(t); after.accept(t); };
是一个lamda表达式,得到一个实现了accept()方法的Consumer对象。这里accept()方法的内容相当于:
void accept(T t){
this.accept(t);
after.accept(t);
};
this.accept(t); 是调用当前对象的accept方法
after.accept(t); 是调用传进来的after的accept方法
例:
public static void main(String[] args) {
Consumer<String> a = (String s)-> System.out.println("打印机1:"+s);
Consumer<String> a1 = (String s)-> System.out.println("打印机2:"+s);
a.andThen(a1).accept("打印内容");
}
如果对lamda表达式不熟悉参考文章:java中的Lamda表达式
如上代码中, a.andThen(a1)返回的是Consumer对象,
该对象的accept()方法:
(伪代码)
void accept(T t){
a.accept(t);
a1.accept(t);
}
2、 Consumer 使用实例
2.1、forEach(Consumer<? super T> action)
java 中list、map等集合中实现了forEach方法,forEach源码示例如下:
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
使用实例:
public static void main(String[] args) {
List<String> list = Arrays.asList("张三","李四","王五");
list.forEach((s)-> System.out.println(s));
}
// 输出
张三
李四
王五
Process finished with exit code 0
2.2、格式化打印信息 实例
public static void main(String[] args) {
String[] array = { "大雄,男", "静香,女", "胖虎,男" };
printInfo(
s -> System.out.print("姓名:" + s.split(",")[0] + ","),
s -> System.out.println("性别:" + s.split(",")[1] + "。"),
array
);
}
private static void printInfo(Consumer<String> one, Consumer<String> two, String[] array) {
for (String info : array) {
one.andThen(two).accept(info);
}
}
输出
姓名:大雄,性别:男。
姓名:静香,性别:女。
姓名:胖虎,性别:男。