Java 中常用的函数式接口Consumer

写在前面

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);
}

接口2interface 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);
        }
    }

输出

姓名:大雄,性别:男。
姓名:静香,性别:女。
姓名:胖虎,性别:男。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值