看不到功能接口 'Consumer' 和 'Supplier' 的意义
Failing to see the point of the Functional interfaces 'Consumer' and 'Supplier'
我实现了Predicate
和Function
的用法,分别用于将松散耦合的条件和函数传递给方法。
谓词经常用于过滤 java 流,例如
list.stream().filter(aPredicate).collect();
和功能:
list.stream().forEach(aFunction);
我没有看到 'Consumer' 和 'Supplier' 的类似用例。一个简单的例子 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");
对我来说似乎是不必要的添加代码,也许那个例子没有显示出它的威力。
您的 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
经常使用,在您只想打印一些东西的情况下,或者将值保存到 database/file 而您并不真正关心 return 值的情况。
Supplier<T>
input: nothing, output: value of type T. 这可能是最不常见的,因为人们在使用 lambda 时通常从 Collection 开始。但是当你想生成你自己的流时,Supplier 很有用,例如,如果你想生成一个无限的质数流,那么从一个 List 开始是没有办法做到这一点的。
供应商的另一个具体示例是当一个功能需要新对象时,当场创建,例如 Collectors.toCollection(Supplier<C> factory)
。例如:
List<T> list = stream.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
在这里,我们传递一个“供应商”……一个不带参数的函数,返回一个值……给 toCollection
方法。
没有 Supplier
类型,我们无法表达。
我实现了Predicate
和Function
的用法,分别用于将松散耦合的条件和函数传递给方法。
谓词经常用于过滤 java 流,例如
list.stream().filter(aPredicate).collect();
和功能:
list.stream().forEach(aFunction);
我没有看到 'Consumer' 和 'Supplier' 的类似用例。一个简单的例子 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");
对我来说似乎是不必要的添加代码,也许那个例子没有显示出它的威力。
您的 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
经常使用,在您只想打印一些东西的情况下,或者将值保存到 database/file 而您并不真正关心 return 值的情况。
Supplier<T>
input: nothing, output: value of type T. 这可能是最不常见的,因为人们在使用 lambda 时通常从 Collection 开始。但是当你想生成你自己的流时,Supplier 很有用,例如,如果你想生成一个无限的质数流,那么从一个 List 开始是没有办法做到这一点的。
供应商的另一个具体示例是当一个功能需要新对象时,当场创建,例如 Collectors.toCollection(Supplier<C> factory)
。例如:
List<T> list = stream.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
在这里,我们传递一个“供应商”……一个不带参数的函数,返回一个值……给 toCollection
方法。
没有 Supplier
类型,我们无法表达。