当前位置: 首页 > 知识库问答 >
问题:

收集器(Java)中的groupingby和mapping有什么区别?

须景辉
2023-03-14
// group by price, uses 'mapping' to convert List<Item> to Set<String>
    Map<BigDecimal, Set<String>> result =
            items.stream().collect(
                    Collectors.groupingBy(Item::getPrice,
                            Collectors.mapping(Item::getName, Collectors.toSet())
                    )
            );

groupingBy和Mapping可以互换吗?他们有什么不同?

对于collect()中的第三个参数,如果我使用collectors.toList()而不是collectors.toSet(),会得到相同的输出类型映射吗?我听说toList()是一个更流行的选项。

共有1个答案

张嘉熙
2023-03-14

不,两者完全不同。

collectors.groupingby接受一个函数,该函数创建键并返回一个收集器,该收集器返回从键到流中具有相同键的对象集合的映射。

collectors.mapping则接受一个函数和另一个收集器,并创建一个新的收集器,该收集器首先应用该函数,然后使用给定的收集器收集映射的元素。因此,以下内容是等同的:

items.stream().map(f).collect(c);
items.stream().collect(Collectors.mapping(f, c));

collectors.mapping在没有流但需要直接传递收集器的情况下最有用。使用collectors.groupingby时就是这种情况的一个例子。

items.stream().collect(Collectors.groupingBy(Item::getPrice, Collectors.toSet()))

生成映射 (假设getPrice()返回bigdecimal)。然而,

items.stream().collect(Collectors.groupingBy(Item::getPrice,
    Collectors.mapping(Item::getName, Collectors.toSet())))

返回映射 > 。在收集项之前,它首先对它们应用item.getname

 类似资料:
  • 为什么并行流使用合并器类,而顺序流将使用累加器?为什么并行流不使用累加器? 以下是上述代码的输出: 那么,为什么顺序流使用累加器,并行流使用组合器?并行流不能使用累加器吗?

  • 我试图了解两者之间是否有任何重大差异。在查看示例时,我注意到它使用了完全相同的二进制和arg(https://github.com/open-telemetry/opentelemetry-collector/blob/main/examples/demo/docker-compose.yaml). 唯一的区别是配置文件在导出器/接收器方面有所不同。因此,唯一的区别是使用什么endpoint来收集

  • 问题内容: 我正在关注Go教程,由于无法理解特定的方法签名而陷入困境: 该文档解释如下: 该方法的签名如下:“这是一个名为save的方法,它的接收方p是指向Page的指针。它不带参数,并且返回错误类型的值。” 我不明白接收器是什么。我将其作为参数读取,但随后我期望参数位于中。 问题答案: 接收者是声明方法的对象。 要向对象添加方法时,请使用此语法。 例如:http://play.golang.or

  • 问题内容: 我一直认为Java 中的运算符用于验证其两个布尔操作数是否均为,并且该&运算符用于对两种整数类型进行按位运算。 最近我知道,也可以使用运算符来验证其两个布尔操作数是否均为,唯一的区别是即使LHS操作数为false,它也会检查RHS操作数。 Java中的运算符是否在内部重载?还是在这背后有其他概念? 问题答案: <-验证两个操作数 <-停止评估第一个操作数是否为false,因为结果为fa

  • 问题内容: 我是Java新手,对Java中的垃圾收集器感到困惑。它实际上是做什么的,什么时候生效。请描述Java中垃圾收集器的一些属性。 问题答案: 该垃圾收集器是运行在一个程序的Java虚拟机,其摆脱其未使用的Java应用程序了对象。它是自动内存管理的一种形式。 当典型的Java应用程序运行时,它正在创建新的对象,例如和,但是在一段时间之后,这些对象将不再使用。例如,看下面的代码: 在上面的代码

  • 问题内容: 是什么决定了垃圾收集器何时真正收集?它是在一定时间之后还是在一定数量的内存用完之后发生的吗?还是还有其他因素? 问题答案: 它在确定是时候运行时运行。在世代垃圾收集器中,一种常见的策略是在第0代内存分配失败时运行收集器。也就是说,每次你分配一小块内存(大块通常直接放置在“旧”代中)时,系统都会检查gen-0堆中是否有足够的可用空间,如果没有,则运行GC释放空间以使分配成功。然后将旧数据