在Java中创建元组和元组函数的助手方法?

在Java中创建元组和元组函数的助手方法?,java,java-8,tuples,apache-commons-lang3,Java,Java 8,Tuples,Apache Commons Lang3,我正在使用Java8和ApacheCommonsLang3中的两个 我尝试做的第一件事是从列表中获取流,并使用函数最终创建一个列表。目前,我正在创建一个带有我想要的特定类型的函数,并使用它来映射流。我想要的是: public static <T, U> Function<T, Pair<T, U>> tupledResult(final Function<T, U> generator) { Objects.requireNonNull(g

我正在使用Java8和ApacheCommonsLang3中的两个

我尝试做的第一件事是从
列表
中获取流,并使用
函数
最终创建一个
列表
。目前,我正在创建一个带有我想要的特定类型的
函数
,并使用它来映射流。我想要的是:

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));
}
ApacheCommonsLang3中是否有这样的功能,或者我应该自己开发?如果是后者,这是有益的贡献还是糟糕的解决方案

示例

这就是我想要实现的目标:

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);
    }));
}
private void doStuff(最终列表){
最终列表otherThings=things.stream()
.map(tupledResult(ThingHelper::generateOther))
.collect(Collectors.toList());
otherThings.stream().forEach(tuple((final Thing,final Other)->{
doSomething(事物、其他);
}));
otherThings.stream().forEach(tuple((final Thing,final Other)->{
doSomethingElse(事物、其他);
}));
}
这里的要点是
ThingHelper.generateOther
相对昂贵,我只想做一次。此外,必须先将
doSomething
应用于所有内容,然后再将
doSomethingElse
应用于所有内容

这些对永远不会离开这个方法的作用域,我也不想重载这些方法来获取一对。在这种情况下,我真的不关心对的语义缺失,重要的是顺序
doSomething
doSomethingElse
提供语义。

在FunctionalJava()中,我会:



    private void doStuff(final List<Thing> things) {
        fj.data.List<P2<Thing, Other>> otherThings = fj.data.List.list(things)
            .map(t -> P.p(t, ThingHelper.generateOther.apply(t)));
        otherThings.forEachDoEffect(p -> doSomething(p._1(), p._2()));
        otherThings.forEachDoEffect(p -> doSomethingElse(p._1(), p._2()));
    }


私人无效文件(最终清单){
fj.data.List otherThings=fj.data.List.List(事物)
.map(t->P.P(t,ThingHelper.generateOther.apply(t));
其他方面。forEachDoEffect(p->doSomething(p._1(),p._2());
其他方面。forEachDoEffect(p->doSomethingElse(p._1(),p._2());
}

元组作为类p、P1、P2等()的产品受到支持。

在Apache Commons Lang3中没有此类方法,因为此库与Java 6兼容,但所需的方法必须返回仅在Java 8中出现的
Java.util.function
包的对象

如果您的
对象不重复,那么在您的情况下使用
映射
是很自然的:

private void doStuff(final List<Thing> things) {
    final Map<Thing, Other> otherThings = things.stream()
        .collect(Collectors.toMap(Function.identity(), ThingHelper::generateOther));
    otherThings.forEach((final Thing thing, final Other other) -> {
        doSomething(thing, other);
    });
    otherThings.forEach((final Thing thing, final Other other) -> {
        doSomethingElse(thing, other);
    });
}
private void doStuff(最终列表){
最终映射otherThings=things.stream()
.collect(Collectors.toMap(Function.identity(),ThingHelper::generateOther));
其他事物。forEach((最终事物,最终其他)->{
doSomething(事物、其他);
});
其他事物。forEach((最终事物,最终其他)->{
doSomethingElse(事物、其他);
});
}
甚至更短:

private void doStuff(List<Thing> things) {
    Map<Thing, Other> otherThings = things.stream()
        .collect(toMap(x -> x, ThingHelper::generateOther));
    otherThings.forEach(this::doSomething);
    otherThings.forEach(this::doSomethingElse);
}
private void doStuff(列出事物){
Map otherThings=things.stream()
.collect(toMap(x->x,ThingHelper::generateOther));
其他事物。forEach(这个::doSomething);
其他事物。forEach(这个::doSomethingElse);
}

这样,您就不需要包装器了,因为它已经接受了
BiConsumer
,第二个参数基本上取代了
tupledResult

,这是一个真正需要考虑的问题:。有趣的是,java有很多
Bi-
类型;但它坚决拒绝拥有
@bayou.io:这些
Bi
-类型是无状态函数,与作为存储的
类型不同。它的添加被延迟,因为他们想等待真正的值类型,但是
Optional
也被添加,作为一种值类型,JVM中还没有真正的值类型。除此之外,还有一个pair类型,如果你能接受它的不切实际的名称
AbstractMap.SimpleImmutableEntry
。@Steiny:你不应该需要这个冗长的lambda语法
(final Thing Thing,final Other)->{doSomething(Thing,Other);}
一个简单的
(Thing,Other)->doSomething(Thing,Other)
也应该可以。或者方法引用…您可以删除
final
修饰符,使代码更加简洁。这会更好。我喜欢。不知道为什么我要避免使用地图,因为这些事情不会重复。
private void doStuff(List<Thing> things) {
    Map<Thing, Other> otherThings = things.stream()
        .collect(toMap(x -> x, ThingHelper::generateOther));
    otherThings.forEach(this::doSomething);
    otherThings.forEach(this::doSomethingElse);
}