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

为什么mapMulti与flatMap相比需要类型信息

沈嘉瑞
2023-03-14

我想使用mapMulti而不是flatMap,并重构了以下代码:

// using flatMap (version 1) => returns Set<Item>
var items = users.stream()
                 .flatMap(u -> u.getItems().stream())
                .collect(Collectors.toSet());

这个(版本2):

// using mapMulti (version 2) => returns Set<Item>
var items = users.stream()
                 .<Item>mapMulti((u, consumer) -> u.getItems().forEach(consumer))
                 .collect(Collectors.toSet());

两者都返回相同的元素。然而,我怀疑我是否真的应该用mapMulti的更详细的代码替换我所有的flatMap。为什么我需要在mapMuli()之前添加类型信息。


共有1个答案

颛孙品
2023-03-14

请注意,当使用flatMap时,推断结果流类型所需的类型推断与使用mapMulti时非常不同。

使用flatMap时,生成流的类型与lambda主体的返回类型相同。这是一个特殊的东西,编译器被设计用来推断类型变量(即编译器“知道”它)。

然而,在mapMulti的情况下,您可能想要的结果流的类型只能从您对消费者lambda参数所做的事情中推断出来。假设,编译器的设计可以使,例如,如果你说消费者。accept(1),然后它会查看您传递给accept的内容,并查看您想要一个

基本上,您要求编译器根据lambda中任意表达式的类型推断lambda的参数类型。编译器并不是专门为实现这一点而设计的。

除了添加

使lambda显式键入:

var items = users.stream()
             .mapMulti((User u, Consumer<Item> consumer) -> u.getItems().forEach(consumer))
             .collect(Collectors.toSet());

添加一个临时流变量:

// By looking at the type of itemStream, the compiler can figure out that mapMulti should return a Stream<Item>
Stream<Item> itemStream = users.stream()
             .mapMulti((u, consumer) -> u.getItems().forEach(consumer));
var items = itemStream.collect(Collectors.toSet());

我不知道这是否更“简化”,但我认为如果使用方法引用,会更整洁:

var items = users.stream()
             .map(User::getItems)
             .<Item>mapMulti(Iterable::forEach)
             .collect(Collectors.toSet());

 类似资料:
  • 问题内容: 我开始使用RxJS,但我不明白为什么在此示例中我们需要使用类似or 的函数;数组的数组在哪里? 如果有人可以直观地解释正在发生的事情,那将非常有帮助。 问题答案: 当您有一个Observable的结果是更多Observable时,可以使用flatMap。 如果您有一个由另一个可观察对象产生的可观察对象,则您不能直接过滤,缩小或映射它,因为您有一个可观察对象而不是数据。如果您生成一个可观

  • 为什么需要泛型 前言 泛型程序最早出现1970年代的CLU和Ada语言中, 后来被许多机遇对象和面向对象的语言锁采用 1993年C++在3.0版本中引入的模板技术就属于泛型编程 1994年7月ANSI/ISO C++标准委员会通过的STL更是泛型编程的集大成者, 它已被纳入1998年9月C++标准之中. 2004年9月Java在J2SE 5.0(JDK 1.5)中开始使用泛型技术; 2005年11

  • 我在互联网上找到了例子,但这并没有给我充分的理解。使用WebFlux时的标准CRUD。 路由器: 处理程序: 我是对的还是这个说法错了?

  • 休假后回来:)带着问题。我正在阅读比较接口留档从比较文档。我明白,我们使用可比,因为它将为我们提供排序和自然排序。在留档中,它被写成。 强烈建议(尽管不是必需的)自然顺序与equals一致。这是因为没有显式比较器的排序集(和排序映射)在与自然顺序与equals不一致的元素(或键)一起使用时表现“奇怪”。特别是,这样的排序集(或排序映射)违反了用equals方法定义的set(或映射)的一般约定。 “

  • 我读了一些关于如何使用log4j的文章。他们中的大多数给出以下代码作为开始: 或 这将初始化记录器对象。但是我的问题是为什么需要发送类类型作为参数?似乎当我使用记录器时,我不在乎在哪个类中使用它。所以类类型似乎对记录器没有影响。如果我声明一个记录器为静态和公共的,我可以在另一个类中调用这个记录器,那么作者这样设计它的意图是什么?当我使用记录器时,类类型会绑定一些东西吗?或者我可以发送任何类类型到g

  • 问题内容: 我需要了解我正在研究的项目的ELF文件布局,并且注意到这些工具的存在。为什么所有Linux发行版都同时包含readelf和objdump?这些工具相互补充吗?我何时更愿意使用一个? 问题答案: 来自binutils / readelf.c: