从JDK8开始java支持函数式编程,JDK也提供了几个常用的函数式接口,这篇主要介绍Consumer接口。
文本介绍的顺序依次为:

  • 源码介绍
  • 使用实例
  • jdk内对Consumer的典型使用
  • 扩展类介绍

源码介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package java.util.function;

import java.util.Objects;

/**
*
* 表示“接受一个参数输入且没有任何返回值的操作“。不同于其它的函数式接口,Consumer期望通过方法的实现来执行具体的操作。
*/
@FunctionalInterface
public interface Consumer<T> { /**
* 可实现方法,接受一个参数且没有返回值
*/
void accept(T t); /**
*
* 默认方法,提供链式调用方式执行。执行流程:先执行本身的accept在执行传入参数after.accept方法。
* 该方法会抛出NullPointerException异常。
* 如果在执行调用链时出现异常,会将异常传递给调用链功能的调用者,且发生异常后的after将不会在调用。
*
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}

源码只有2个方法,也比较容易理解,我们下面来看一下具体的使用方法。

使用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package jdk8;

import java.util.function.Consumer;

public class ConsumerTest {

    public static void main(String[] args) {
testConsumer();
testAndThen();
} /**
* 一个简单的平方计算
*/
public static void testConsumer(){
Consumer<Integer> square = x -> System.out.println("print square : " + x * x);
square.accept(2);
} /**
* 定义3个Consumer并按顺序进行调用andThen方法,其中consumer2抛出NullPointerException。
*/
public static void testAndThen(){
Consumer<Integer> consumer1 = x -> System.out.println("first x : " + x);
Consumer<Integer> consumer2 = x -> {
System.out.println("second x : " + x);
throw new NullPointerException("throw exception test");
};
Consumer<Integer> consumer3 = x -> System.out.println("third x : " + x); consumer1.andThen(consumer2).andThen(consumer3).accept(1);
}
}

下面是执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
print square : 4

first x : 1
second x : 1
Exception in thread "main" java.lang.NullPointerException: throw exception test
at jdk8.ConsumerTest.lambda$testAndThen$2(ConsumerTest.java:27)
at java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
at java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
at jdk8.ConsumerTest.testAndThen(ConsumerTest.java:31)
at jdk8.ConsumerTest.main(ConsumerTest.java:9) Process finished with exit code 1

在testAndThen()方法的执行结果可以看到打印的顺序和出现异常的情况(third x : 1 并没有输出)
上面只是一个简单的使用,主要为了说明使用方式。对于Consumer的工作实践目前还未使用,并没有好的例子。

jdk内对Consumer的典型使用

在jdk内对Consumer的典型使用非foreach莫属了(在 java.lang.Iterable内),下面是源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Performs the given action for each element of the {@code Iterable}
* until all elements have been processed or the action throws an
* exception. Unless otherwise specified by the implementing class,
* actions are performed in the order of iteration (if an iteration order
* is specified). Exceptions thrown by the action are relayed to the
* caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* for (T t : this)
* action.accept(t);
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}

方法接收一个Consumer对象,对this集合执行循环相同的操作。

TODO:除Iterable外还有很多地方使用到了Consumer,待后续使用到在添加。

扩展类介绍

Consumer的accept只接受一个参数,那如果要是想使用多个参数要怎么办?jdk8又提供了一个BiConsumer接口类,该类与Consumer的区别是可以接受2个参数。

jdk8还对Consumer和BiConsumer各提供了3个常用的相关接口类,见下表:

   
类名 描述
IntConsumer 接受单个int型参数的Consumer操作
DoubleConsumer 接受单个double型参数的Consumer操作
LongConsumer 接受单个long型参数的Consumer操作
ObjIntConsumer 接受2个int型参数的Consumer操作,不支持andThen方法
ObjDoubleConsumer 接受2个double型参数的Consumer操作,不支持andThen方法
ObjLongConsumer 接受2个long型参数的Consumer操作,不支持andThen方法

转载链接:http://www.sanjinbest.com/uncategorized/JAVA-8-函数式接口-Consumer/

JAVA 8 函数式接口--Consumer的更多相关文章

  1. Java常用函数式接口--Consumer接口andThen()方法使用案例(二)

    Java常用函数式接口--Consumer接口使用案例

  2. Java常用函数式接口--Consumer接口使用案例

    第一种方式: 第二种方式:

  3. Java 8 函数式接口

    函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为 lambda 表达式. Lambda 表达式和方法引用 ...

  4. Java 8 新特性-菜鸟教程 (3) -Java 8 函数式接口

    Java 8 函数式接口 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为lambda表达式. 函数式接 ...

  5. Java 8函数式接口functional interface的秘密

    Java 8函数式接口functional interface的秘密 2014年10月29日 17:52:55 西瓜可乐520 阅读数:3729   目录 [−] JDK 8之前已有的函数式接口 新定 ...

  6. Java之函数式接口@FunctionalInterface详解(附源码)

    Java之函数式接口@FunctionalInterface详解 函数式接口的定义 在java8中,满足下面任意一个条件的接口都是函数式接口: 1.被@FunctionalInterface注释的接口 ...

  7. Java常用函数式接口--Predicate接口使用案例

    Java常用函数式接口--Predicate接口使用案例 该方法可以使用and来优化: 调用:

  8. Java函数式接口Consumer

    Consumer是java8提供的函数式接口之一,意思为消费者,接受参数而不返回值 void accept(T t); default Consumer<T> andThen(Consum ...

  9. JAVA 8 函数式接口 - Functional Interface

    什么是函数式接口(Functional Interface) 其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法. 这种类型的接 ...

随机推荐

  1. Egret_简单的封装方法

    ////////////随机颜色***////////////////////////// private getRdmClr(): number { return (Math.floor(Math. ...

  2. linux三剑客之grep

    linux基础三剑客之grep 1.grep命令 基本介绍 grep命令是文本本过滤工具,是基于一个模式匹配文件的每一行,grep分类:egrep个fgrep. grep英文名:Global  sea ...

  3. spring注解注入:<context:component-scan>详解

    spring从2.5版本开始支持注解注入,注解注入可以省去很多的xml配置工作.由于注解是写入java代码中的,所以注解注入会失去一定的灵活性,我们要根据需要来选择是否启用注解注入. 我们首先看一个注 ...

  4. javascript 4.1 美术馆

    1.把images文件夹放在html文件同一文件夹子目录下,可以在html中引用图片 例如<a href="images/rose.jpg" title="A re ...

  5. 使用OpenLDAP部署目录服务

  6. oracle 中update多个字段

    update  A set (A.a2,A.a3) =(select B.b2,b.b3 from  B where B.b1= A.a1 and A.a3=100 )

  7. 手写SpringMVC实现

    设计自己的MVC架构 1.读取配置通过web.xml中加载我们自己写的MyDispatcherServlet和读取配置文件. 2.初始化九大组件只需实现基本的:1).加载配置文件:2).扫描用户配置包 ...

  8. 安装owncloud出现:Error while trying to create admin user: An exception occurred while executing

    安装owncloud出现:Error while trying to create admin user: An exception occurred while executing 1.安装ownc ...

  9. 北京U3D外包团队 UE4红军抗战案例 Unity3D红军抗战案例 UE4下载和安装虚幻4游戏引擎

    刚完整UE4红军抗战案例 Unity3D红军抗战案例,有在线演示(版权关系不方便发图),有UE4或Unity项目定制外包开发的欢迎联系我们 进入虚幻4的官方主页(https://www.unreale ...

  10. v4l2框架分析

    参考:https://www.cnblogs.com/fengong/p/4424823.html    http://www.cnblogs.com/fengong/p/4424895.html 一 ...