未能看到功能界面“消费者”和“供应商”的重点

时间:2017-09-29 23:32:35

标签: java functional-programming functional-interface

我意识到PredicateFunction的用法,分别用于将松散耦合的条件和函数传递给方法。

谓词经常用于过滤java流,例如

list.stream().filter(aPredicate).collect();

和功能:

list.stream().forEach(aFunction);

我没有看到“消费者”和“供应商”的类似用例。一个简单的例子here有这段代码:

Consumer consumer = ConsumerTest::printNames;

consumer.accept("Jeremy");
consumer.accept("Paul");
consumer.accept("Richard");

其中printNames是一个简单的方法:

private static void printNames(String name) {
    System.out.println(name);
}

我不明白为什么我不会这样做:

Consumer consumer = ConsumerTest::printNames;

printNames("Jeremy");
printNames("Paul");
printNames("Richard");

看起来像是不必要的添加代码,也许这个例子没有显示它的力量。

2 个答案:

答案 0 :(得分:2)

list.stream().forEach(aFunction);的示例实际上是错误的,forEach需要Consumer<? super T>而不是Function<T,R>

这些功能界面的关键在于函数的形状,换句话说,输入和输出。这些接口的输出。

使用您提供的界面:

Predicate<T>输入:类型为T的值,输出:布尔值,由filter大量使用。

Function<T,R>输入:类型T的值,输出:类型R的值。有点像转换,map使用很多。

Consumer<T>输入:类型T的值,输出:void / nothing。 forEach大量使用,在您只想打印出来的情况下,或者将值保存到您并不真正关心返回值的数据库/文件中。

Supplier<T>输入:没有,输出:类型为T的值。这可能是最不常见的,因为人们在使用lambda时经常以Collection开头。但是,当您想要生成自己的流时,供应商很有用,例如,如果要生成无限的素数流,则无法通过以列表开头来实现。

答案 1 :(得分:2)

供应商的另一个具体示例是,当场创建的函数需要新的Object,例如Collectors.toCollection(Supplier<C> factory)。例如:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    int a;

    ifstream inputfile;
    //declare an input file
    inputfile.open("text.txt");

    while(//not sure best way to do this part)
    {
            //guessing I can use a for loop and place numbers in array 
            //based on first number in the row of numbers
    }

    return 0;
}

在这里,我们传递一个“供应商”......一个不带参数的函数,将一个值...返回给List<T> list = stream.collect(Collectors.toCollection(CopyOnWriteArrayList::new)); 方法。

如果没有toCollection类型,我们就无法表达。