Consumer

Jan 15, 2018


JDK1.8增加了一个Consumer接口,现在就来探究一下。

后记

后记为啥要放最前面?因为懒得拖到最下面啊,O(∩_∩)O哈哈哈~

除了这个支持泛型的 Consumer 接口,又发现了三个很类似的接口
DoubleConsumer、IntConsumer、LongConsumer
这三个接口只接收对应类型的值,即Double、Int、Long

另外还有接收两个泛型参数的 BiConsumer 接口
其也有三个变形接口:ObjDoubleConsumer、ObjIntConsumer、ObjLongConsumer
这三个变形接口第一个参数支持泛型,第二个参数分别支持Double、Int、Long
值得注意的是这三个变形接口没有 andThen 方法

源码

/**
 * Represents an operation that accepts a single input argument and returns no
 * result. Unlike most other functional interfaces, {@code Consumer} is expected
 * to operate via side-effects.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #accept(Object)}.
 *
 * @param <T> the type of the input to the operation
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

翻译

/**
 * 表示接受单个输入参数并不返回结果的操作。
 * 和大多数函数式接口不同,Consumer接口预计将通过副作用进行操作。
 *
 * 这是一个函数式接口,其函数式方法是accept。
 *
 * @param <T> 操作的输入类型
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Consumer<T> {

    /**
     * 在给定的参数上执行此操作.
     *
     * @param t 输入的参数
     */
    void accept(T t);

    /**
     * 返回一个有序的Consumer操作组合, 本操作执行之后执行after操作。
     * 如果任意操作执行时抛出异常,则将异常反馈到操作组合的调用方。
     * 如果本操作执行时抛出异常,则不会执行after操作。
     *
     * @param after 本操作之后执行的操作
     * @return 一个有序的操作组合,本操作执行之后执行after操作
     * @throws NullPointerException 如果after操作为null则抛空指针异常
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

摘要

  1. Consumer接口是函数式接口,其accept方法没有返回值
  2. Consumer接口通过副作用进行操作,我理解的就是在原来对象上进行更改(不知道对不对,😓,没有找到靠谱的资料)

实例

定义一个对象:

public class Student {
	private int id;
	private String name;
	private int age;
	
	public Student(int id, String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setAge(int age) {
		this.age = age;
} }

实例1:

Student student = new Student(1, "lin", 20);
System.out.println(student.toString());

Consumer<Student> c1 = s -> s.setName("chen");
c1.accept(student);
System.out.println(student.toString());
	
输出结果为:
Student [id=1, name=lin, age=20]
Student [id=1, name=chen, age=20]

实例2:

Student student = new Student(1, "lin", 20);
System.out.println(student.toString());

Consumer<Student> c1 = s -> s.setId(2);
Consumer<Student> c2 = s -> s.setName("chen");
Consumer<Student> c3 = s -> s.setAge(18);
c3.andThen(c2).andThen(c1).accept(student);
System.out.println(student.toString());

输出结果为:
Student [id=1, name=lin, age=20]
Student [id=2, name=chen, age=18]