当前位置: 首页 > 面试题库 >

未调用Stream.map/filter中的Lambda

岑炯
2023-03-14
问题内容

我正在尝试List通过将它们添加到Set和中ListStream.filter并在中找到单独的重复项和非重复项Stream.map

List<String> strings = Arrays.asList("foo", "bar", "foo", "baz", "foo", "bar");

Set<String> distinct = new HashSet<>();
List<String> extras = new ArrayList<>();

strings
  .stream()
  .filter(x -> !distinct.add(x))
  .map(extra -> extras.add(extra));

在本月底,我希望distinct[foo, bar, baz]extras[foo, foo, bar],因为有2个额外的实例foo和1 bar。但是,运行此命令后,它们都为空。

永远不会调用提供给该流的lambda,我通过尝试在内部打印进行验证map

.map(extra -> {
  System.out.println(extra);
  return extras.add(extra);
})

当我尝试putMap任何一个一起使用时,这将不起作用。我究竟做错了什么?

注意:可能还有其他与此类似的问题,但是我正在寻找一种规范的答案,以说明这种问题为什么不适用于Java
8的Streams。如果您可以提出一个更笼统的问题(即使意味着完全更改它),我将不胜感激。


问题答案:

两个Stream#filterStream#map是中间操作,这意味着它们被懒惰地评估。根据文档:

中间操作返回一个新的流。他们总是很懒惰。执行诸如filter()之类的中间操作实际上并不会执行任何过滤,而是会创建一个新的流,该流在遍历时将包含与给定谓词匹配的初始流的元素。在执行管道的终端操作之前,不会开始遍历管道源。

无论如何,您都应该使用适当的方法来避免此类错误。forEach应该用来代替流,map因为Stream#map它用于将流转换为在每个元素上调用映射函数的结果,而Stream#forEach用于对其进行迭代。

演示:https :
//ideone.com/ZQhLJC

strings
  .stream()
  .filter(x -> !distinct.add(x))
  .forEach(extras::add);

另一个可能的解决方法是执行终端操作,例如.collect强制应用过滤器和地图。

strings
  .stream()
  .filter(x -> !distinct.add(x))
  .map(extra -> extras.add(extra)).collect(Collectors.toList());

如果要使用.collect,则最好使用收集的列表,extras以避免浪费时间和空间。

List<String> extras = strings
  .stream()
  .filter(x -> !distinct.add(x)).collect(Collectors.toList());


 类似资料:
  • 示例: [1,“Desc”,...,...,1] [1,“Desc”,...,...,2] 稍后,我想对的这个执行一些操作: [[1,“Desc”,...,...,1],[1,“Desc”,...,...,2],...] 并且我正在尝试以以下方式使用Stream.Map: 我如何打印,然后开始对列表中的每个项执行操作?

  • 问题内容: 我是新手并尝试学习过滤器的概念,但在我的情况下是两次调用过滤器,我期望过滤器只运行一次,但运行两次。不能理解为什么会这样。 这是我的 朋克 … 问题答案: 如果我没有把你的问题弄错的话,这就是这里的问题 Angularjs 使用“脏检查”方法,因此需要调用所有过滤器以查看是否存在任何更改。此后,它检测到一个变量(您键入的变量)有变化,然后再次执行所有过滤器以检测是否有其他变化。 这是另

  • 问题内容: 实例化ArrayAdapter时,我收到以下警告(编译正常): 这是问题所在: 有人对它为什么给我这个警告有任何想法吗? 问题答案: 这是因为希望您指定它将处理的对象类型。因此,为了避免这些警告,请执行以下操作:

  • 问题内容: 我试图绘制一个简单的矩形,但我认为paintComponent方法没有被调用。这是带有main方法的类的代码: 和带有paintComponent()的类 这是什么问题,我不知道… 问题答案: 虽然已经提供的答案可能会导致出现矩形,但这种方法并非最佳。此示例旨在显示一种更好的方法。阅读代码中的注释以获取详细信息。 请注意,应该在EDT上启动Swing / AWT GUI。这留给读者练习

  • 谁能帮助我理解我做错了什么,以及我如何触发onRequestPermissionsResult,以便我可以在应用程序中启动下一个活动?

  • 问题内容: 如果从调用, 则会 收到消息 “套接字已连接” ,但未调用。我在这里想念什么? 问题答案: 在AngularJS中,承诺结果在$ digest周期内异步传播。因此,仅在进入$ digest循环时才调用在then()中注册的回调函数。 因此,当您的套接字连接时,我们处于摘要周期。 创建一个新的Promise,但是直到下一个摘要周期(永远不会到来的摘要周期)之前,它的结果才会传播(因为没有