将消费者转换为function
Function
接口的许多lambda都采用了这种forms
t -> { // do something to t return t; }
我经常这样做,所以我已经为此编写了一个方法。
static Function consumeThenReturn(Consumer consumer) { return t -> { consumer.accept(t); return t; }; }
这使我能够做到这样的非常好的事情:
IntStream.rangeClosed('A', 'Z') .mapToObj(a -> (char) a) .collect(Collectors.collectingAndThen(Collectors.toList(), consumeThenReturn(Collections::shuffle))) .forEach(System.out::print);
还有另一种方法可以在不依赖我自己的方法的情况下进行这样的转换吗? 我错过的新API中有什么东西让我的方法多余吗?
有许多可能有用的方法可以添加到Function
, Consumer
和Supplier
接口中。 您举了一个很好的例子(将Consumer
转换为Function
),但还有许多其他潜在的转换或实用程序可以添加。 例如,使用Function
as Consumer
(通过忽略返回值)或作为Supplier
(通过提供输入值)。 或者通过提供任一值将BiFunction
转换为Function
。 当然,所有这些都可以在代码中手动完成,或者通过实用程序function提供,但是在API中有标准化机制可能是有价值的,如许多其他语言中所存在的那样。
这是我的猜测,但我猜这反映了语言设计者希望尽可能保持API的清洁。 然而,我对这种语言提供的非常丰富的Comparator
实用程序的对比(作为一个例子)很感兴趣,它可以反转命令,通过几个标准进行比较,处理空值等。这些也很容易留给用户但是由API提供。 我很想知道其中一位语言设计师为什么这些接口的方法看起来如此不一致。
我认为Apache commons集合4.x有你想要的东西。 它与Function
和Consumer
等价物分别是Transformer
和Closure
,它提供了一种使用ClosureTransformer
构成它们的方法ClosureTransformer
通过调用SAM的SAM并将其分配给另一个来转换等效的函数类型是微不足道的。 总而言之,您可以以这种方式结束Java 8 Function
:
Consumer c = System.out::println; Function f = ClosureTransformer.closureTransformer(c::accept)::transform;
c::accept
将Java 8 Consumer
转换为等效的Apache Commons 4 Closure
,而final ::transform
将Apache Commons 4 Transformer
为等效的Java 8 Function
。