Java 8新特性之Consumer

Java 8新特性之Consumer

简介

Java Consumer接口来自Java 8中引入的 java.util.function包。
Consumer是一个功能接口,用来作为lambda表达式或方法引用的任务目标(传递一个参数执行指定的方法)。
\color{red}{ Consumer的功能接口是一个接受单一参数并且不返回任何结果的操作。}
Consumer的功能方法是accept(T t)。

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

如上所示

  1. accept : 这是Consumer功能接口的功能方法。accept 方法对给定的参数进行这一操作。

  2. andThen : 此方法返回一个组合的Consumer,该Consumer先执行原始的Consumer操作,然后按照从左到右的顺序执行给定的andThen操作。

使用示例

import java.util.function.Consumer;

/**
 * @program: mina
 * @description:
 * @author: david.he
 * @create: 2022-04-20
 */
public class ConsumerTest {

    public static void main(String[] args) {
        Consumer<String> nameConsumer = s -> System.out.println(s);
//        等同于
//        Consumer<String> nameConsumer = new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        };
        nameConsumer.accept("Mahesh");
        nameConsumer.accept("Krishna");
    }

}

输出如下

Mahesh
Krishna

使用lambda表达式创建Consumer

  1. 测试简单的lambda表达式
public class ConsumerTest {

    public static void main(String[] args) {
        List<Integer> oddList = new ArrayList<>();
        List<Integer> evenList = new ArrayList<>();

        Consumer<Integer> storeNumber = n -> {
            if (n % 2 == 0) {
                evenList.add(n);
            } else {
                oddList.add(n);
            }
        };

        Consumer<List<Integer>> printList = list -> list.forEach(n -> System.out.println(n));

        storeNumber.accept(10);
        storeNumber.accept(15);
        storeNumber.accept(25);
        storeNumber.accept(30);

        printList.accept(oddList);
        printList.accept(evenList);

    }

}
  1. 操作对象类型
public class ConsumerTest {

    public static void main(String[] args) {
        Consumer<Citizen> electionConsumer = c -> {
            if (c.getAge() < 18) {
                System.out.println(c.getName() + " is not eligible to vote.");
            } else {
                System.out.println(c.getName() + " can vote.");
            }
        };

        electionConsumer.accept(new Citizen("Ritesh", 15));

        electionConsumer.accept(new Citizen("Shreya", 20));
    }
}

class Citizen {
    private String name;
    private int age;

    public Citizen(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }


}

输出结果

Ritesh is not eligible to vote.
Shreya can vote.

使用方法引用的方式创建

public class ConsumerTest {

    public static void main(String[] args) {
        Map<Integer, String> persons = new HashMap<Integer, String>();
        persons.put(101, "Mahesh");
        persons.put(102, "Krishna");

        Consumer<Map<Integer, String>> updatePersons = Utility::updateData;

        Consumer<Map<Integer, String>> displayPersons = Utility::displayData;

        updatePersons.accept(persons);

        displayPersons.accept(persons);
    }
}

class Utility {
    static void updateData(Map<Integer, String> persons) {
        persons.replaceAll((k, v) -> "Shree ".concat(v));
    }

    static void displayData(Map<Integer, String> persons) {
        for (Map.Entry<Integer, String> entry : persons.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }

}

输出结果

101 - Shree Mahesh
102 - Shree Krishna

andThen方法

  1. 这个方法返回一个组合的Consumer,先执行当前Consumer操作,然后再执行after的Consumer操作。
  2. \color{red}{如果这个操作出现异常,那么后面的操作将不会被执行。}
public class ConsumerTest {

    public static void main(String[] args) {
        List<Integer> numList = Arrays.asList(3, 4, 5, 6);

        Consumer<List<Integer>> squareConsumer = list -> {
            for (int i = 0; i < list.size(); i++) {
                list.set(i, list.get(i) * list.get(i));
            }
        };

        Consumer<List<Integer>> printConsumer = list -> list.forEach(n -> System.out.println(n));

        squareConsumer.andThen(printConsumer).accept(numList);
    }
}

输出结果

9
16
25
36

拼接多个addThen

public class ConsumerTest {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(12, 13, 14, 15, 16, 17);

        Consumer<List<Integer>> oddNumConsumer = MyNumber::printOddNum;

        Consumer<List<Integer>> evenNumConsumer = MyNumber::printEvenNum;

        Consumer<List<Integer>> taskFinishConsumer = MyNumber::taskFinishMsg;

        oddNumConsumer.andThen(evenNumConsumer).andThen(taskFinishConsumer).accept(list);

    }
}

class MyNumber {
    static void printOddNum(List<Integer> myNumbers) {
        System.out.println("--- odd numbers ---");
        myNumbers.forEach(n -> {
            if (n % 2 == 1) {
                System.out.print(n + " ");
            }
        });
    }

    static void printEvenNum(List<Integer> myNumbers) {
        System.out.println("\n--- even numbers ---");
        myNumbers.forEach(n -> {
            if (n % 2 == 0) {
                System.out.print(n + " ");
            }
        });
    }

    static void taskFinishMsg(List<Integer> myNumbers) {
        System.out.println("\nTotal " + myNumbers.size() + " number processed.");
    }
}

输出结果

--- odd numbers ---
13 15 17 
--- even numbers ---
12 14 16 
Total 6 number processed.

总结

主要使用场景是:需要操作一个对象,但是不需要返回任何数据。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.Lambda表达式 1.1体验Lambda表达式【理解】 案例需求启动一个线程,在控制台输出一句话:多线程程序...
    西瓜菠萝8800阅读 249评论 0 0
  • 函数式接口 解释 有且只有一个抽象方法的接口 函数式编程的体现就是Lambda,所以函数式接口就是可以适用于Lam...
    abboo阅读 673评论 0 0
  • 函数式接口是什么? 有且只有一个抽象方法的接口被称为函数式接口,函数式接口适用于函数式编程的场景,Lambda就是...
    sanye613阅读 278评论 0 0
  • 其实在java8就已经有java的函数式编程写法,只是难度较大,大家都习惯了对象式用法,但在其它语言中都有函数式的...
    老鼠AI大米_Java全栈阅读 1,034评论 0 3
  • 函数式接口 一、概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口。函数式接口,即适用于函数式编程场景的...
    硅谷干货阅读 1,412评论 0 0