Groovy注入没有类似的Java8Reduce

Groovy注入没有类似的Java8Reduce,groovy,java-8,Groovy,Java 8,通常我认为Groovy的inject方法相当于Java8的reduce,但我似乎遇到了一个不寻常的情况 假设我有一本名叫Book class Book { int id String name } 如果我有一个书籍集合,并希望将它们转换为一个映射,其中键是id,值是书籍,那么在Groovy中,编写以下代码非常简单: Map bookMap = books.inject([:]) { map, b -> map[b.id] = b map } i、 例如,

通常我认为Groovy的
inject
方法相当于Java8的
reduce
,但我似乎遇到了一个不寻常的情况

假设我有一本名叫
Book

class Book {
    int id
    String name
}
如果我有一个书籍集合,并希望将它们转换为一个映射,其中键是id,值是书籍,那么在Groovy中,编写以下代码非常简单:

Map bookMap = books.inject([:]) { map, b ->
    map[b.id] = b
    map
}
i、 例如,对于每本书,将其添加到书id下的地图中,然后返回地图

在Java8中,相同的操作将采用完全不同的方法。或者:

Map<Integer, Book> bookMap = books.stream()
            .collect(Collectors.toMap(Book::getId, b -> b));
不同之处在于风格

然而,我想知道的是,在Java8中是否有类似于Groovy的
inject
reduce
操作。我不能只是模仿我在Groovy中所做的,因为在Java 8中,
reduce
的签名是:

T reduce(T identity, BinaryOperator<T> accumulator)
T reduce(T标识,二进制运算符累加器)
BinaryOperator
意味着lambda表达式的两个元素必须是相同的类型。如果它是一个
双函数
,我可以将lambda的第一个参数设置为
HashMap
,将第二个参数设置为
Book
,但我不能使用
二进制运算符
。我知道有一个三参数版本的
reduce
,但这似乎也没有帮助

我错过了什么明显的东西吗?只是
inject
reduce
更通用吗?因为我已经有了一种用Java解决问题的惯用方法,这并不重要,但这里的差异让我印象深刻。

yoken!:-D

您需要以下条件:

List<Book> books = Arrays.asList(
        new Book(1, "Book One"),
        new Book(2, "Tim's memoirs"),
        new Book(3, "Harry Potter and the sarcastic cat")
);
第一个参数是要收集到的对象:

        new HashMap<Integer, Book>(),
reduce调用中的第三个二进制运算符:

        (a, b) -> {
            a.putAll(b);
            return a;
        }
假设您正在运行并行流,则如何将所有生成的映射重新连接在一起


put
putAll
returning
void
让它变得一团糟:-(但我猜链接在90年代末不是一件流行的事情…

这正是我所需要的。我仍然在纳闷为什么reduce方法是这样设计的(带有一个单独的累加器和合并器),而在Groovy中注入(像往常一样)简单多了,就这样吧。另外,我假设“HP和讽刺猫”中的讽刺猫可能是动物形态的麦格。组合器仅用于
parallel()
streams…如果你在组合器中放入
throw new RuntimeException(“boom”)
,你会看到正常流没有被调用。。。
{
    1=Book{id=1, name='Book One'},
    2=Book{id=2, name='Tim's memoirs'},
    3=Book{id=3, name='Harry Potter and the sarcastic cat'}
}
        new HashMap<Integer, Book>(),
        (map, value) -> {
            map.put(value.id, value);
            return map;
        },
        (a, b) -> {
            a.putAll(b);
            return a;
        }