【发布时间】:2016-02-12 00:18:53
【问题描述】:
我正在使用 Java 8 以及来自 Apache Commons Lang3 的 Pair。
我要做的第一件事是从List<T> 获取流并获取Function<T,U> 并最终创建List<Pair<T,U>>。目前我正在使用我想要的特定类型创建一个Function<T,Pair<T,U>>,并使用它来映射流。我想要的是这样的:
public static <T, U> Function<T, Pair<T, U>> tupledResult(final Function<T, U> generator) {
Objects.requireNonNull(generator);
return (T t) -> new ImmutablePair<>(t, generator.apply(t));
}
下一个问题是,现在我有了List<Pair<T, U>>,我希望能够使用foreach 来应用BiConsumer<T,U>(类似于Scala 中的tupled 函数)。我猜它看起来像:
public static <T, U> Consumer<Pair<T, U>> tupled(final BiConsumer<T, U> consumer) {
Objects.requireNonNull(consumer);
return (final Pair<T, U> p) -> consumer.accept(p.getLeft(), p.getRight());
}
Apache Commons Lang3 中有什么可以做到这一点还是我应该自己推出?如果是后者,这对贡献有用还是不好的解决方案?
示例
这是我想要实现的目标:
private void doStuff(final List<Thing> things) {
final List<Pair<Thing, Other>> otherThings = things.stream()
.map(tupledResult(ThingHelper::generateOther))
.collect(Collectors.toList());
otherThings.stream().forEach(tupled((final Thing thing, final Other other) -> {
doSomething(thing, other);
}));
otherThings.stream().forEach(tupled((final Thing thing, final Other other) -> {
doSomethingElse(thing, other);
}));
}
这里的要点是ThingHelper.generateOther比较贵,我只想做一次。此外,doSomething 必须先应用于所有内容,然后再应用于 doSomethingElse。
对永远不会离开此方法的范围,我也不想重载方法来获取对。在这种情况下,我真的不在乎这对缺乏语义,重要的是顺序。 doSomething 和 doSomethingElse 是提供语义的。
【问题讨论】:
-
有趣的是java有很多
Bi-类型;但它坚决拒绝Pair。 -
@bayou.io:这些
Bi- 类型是无状态函数,与Pair类型不同,后者是一个存储。它的添加已被延迟,因为他们希望等待拥有真值类型,但Optional也已添加,它是一种值类型,但在 JVM 中还没有真值类型。除此之外,还有 一个 pair 类型,如果你能接受它的不切实际的名字AbstractMap.SimpleImmutableEntry... -
@Steiny:你不应该需要这种冗长的 lambda 语法
(final Thing thing, final Other other) -> { doSomething(thing, other); }一个简单的(thing, other) -> doSomething(thing, other)应该也可以。或者方法参考……
标签: java java-8 tuples apache-commons-lang3