首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Groovy插入没有类似的Java 8 reduce

Groovy插入没有类似的Java 8 reduce
EN

Stack Overflow用户
提问于 2016-09-18 00:34:02
回答 1查看 1K关注 0票数 3

通常,我认为Groovy的inject方法等同于Java8的reduce,但我似乎遇到了一种不寻常的情况。

假设我有一个名为Book的POJO (或POGO

代码语言:javascript
运行
复制
class Book {
    int id
    String name
}

如果我有一个书的集合,并且希望将它们转换为一个映射,其中键是it,值是书,那么在Groovy中编写就足够简单了:

代码语言:javascript
运行
复制
Map bookMap = books.inject([:]) { map, b ->
    map[b.id] = b
    map
}

例如,对于每本书,将其添加到地图中的图书id下,并返回地图。

在Java8中,相同的操作将采用完全不同的方法。这两种情况:

代码语言:javascript
运行
复制
Map<Integer, Book> bookMap = books.stream()
            .collect(Collectors.toMap(Book::getId, b -> b));

或者,等同地,

代码语言:javascript
运行
复制
bookMap = books.stream()
            .collect(Collectors.toMap(Book::getId, Function.identity()));

区别在于风格的问题。

然而,我想知道的是,Java8中是否有类似于Groovy中的injectreduce操作。我不能简单地模仿我在Groovy中所做的事情,因为在Java8中,reduce的签名是:

代码语言:javascript
运行
复制
T reduce(T identity, BinaryOperator<T> accumulator)

BinaryOperator意味着lambda表达式的两个元素必须属于同一类型。如果它是一个BiFunction,我可以将lambda的第一个参数设为HashMap<Integer, Book>,将第二个参数设为Book,但我不能用BinaryOperator做到这一点。我知道reduce有一个有三个参数的版本,但这似乎也没有帮助。

我是不是漏掉了什么明显的东西?仅仅是因为injectreduce更通用吗?因为我已经有了用Java解决这个问题的惯用方法,所以这并不重要,但这里的差异给我留下了深刻的印象。

EN

回答 1

Stack Overflow用户

发布于 2016-09-18 01:05:45

Yo Ken!:-D

您需要3 parameter form of reduce,因此给定:

代码语言:javascript
运行
复制
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")
);

您可以执行以下操作:

代码语言:javascript
运行
复制
Map<Integer, Book> reduce = books.stream().reduce(
        new HashMap<Integer, Book>(),
        (map, value) -> {
            map.put(value.id, value);
            return map;
        },
        (a, b) -> {
            a.putAll(b);
            return a;
        }
);

给予:

代码语言:javascript
运行
复制
{
    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'}
}

第一个参数是要收集的内容:

代码语言:javascript
运行
复制
        new HashMap<Integer, Book>(),

第二个参数是一个BiFunction,它接受当前累加器和流中的下一个元素,并以某种方式组合它们:

代码语言:javascript
运行
复制
        (map, value) -> {
            map.put(value.id, value);
            return map;
        },

reduce调用中第三个二元运算符:

代码语言:javascript
运行
复制
        (a, b) -> {
            a.putAll(b);
            return a;
        }

是如何将所有结果映射连接在一起,假设您正在运行并行流...

putputAll returning void把它弄得一团糟:-(但我猜链接在90年代末还不是一件流行的事情……

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39549168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档