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

如何在Java Stream中增加值?

江育
2023-03-14
问题内容

我想index在每次迭代中将的值增加1。轻松实现for-loop。变量image是的数组ImageView

这是我的for-loop

for (Map.Entry<String, Item> entry : map.entrySet()) {      
    image[index].setImage(entry.getValue().getImage());
    index++;
}

为了练习Stream,我尝试将其重写为Stream

map.entrySet().stream()
    .forEach(e -> item[index++].setImage(e.getValue().getImage()));

导致我的错误:

错误:从lambda表达式引用的局部变量必须是final或有效的final

如何重写要在其中使用的Stream递增变量index


问题答案:

你不应该 两者看起来很相似,但是在概念上是不同的。循环只是一个循环,但是一条forEach指令指示库对每个元素执行操作,
而不指定操作顺序(对于并行流)或 执行该操作的 线程 。如果使用forEachOrdered,则 仍然不能保证线程,
但是至少可以保证后续元素上的动作之间发生事前关系。

特别注意文档说:

对于任何给定的元素,可以在库选择的任何时间和线程中执行操作。如果操作访问共享状态,则它负责提供所需的同步。

但是,正如@Marko在下面的注释中指出的那样,即使措辞有些混乱,它也仅适用于并行流。但是,使用循环意味着您甚至不必担心所有这些复杂的事情!

因此,最重要的是:如果该逻辑是其所在函数的一部分,则使用循环;如果forEach您只想告诉Java对流的元素“执行此操作”,则使用循环。

那是关于forEachvs循环。现在讨论为什么变量首先需要为final,以及为什么可以对字段和数组元素进行分类的主题。就像它说的那样,这是因为Java有一个局限性,除非匿名类和lambda永远不会更改,否则它无法访问局部变量。这意味着不仅他们自己不能更改它,而且您也不能在他们外部更改它。但这仅适用于局部变量,这就是为什么它适用于其他所有类(例如类字段或数组元素)的原因。

我认为,这种限制的原因是生命周期问题。局部变量仅在包含它的块正在执行时存在。归功于垃圾回收,其他所有东西都存在,同时有对其的引用。而且所有其他内容还包括lambda和匿名类,因此,如果它们可以修改具有不同生存期的局部变量,则可能导致类似于C
++中悬挂引用的问题。因此,Java采取了简单的方法:它只在创建lambda
/匿名类时复制本地变量。但是,如果您可以更改该变量,则会导致混乱(因为副本不会更改,并且由于副本是不可见的,因此非常混乱)。因此,Java只是禁止对此类变量进行任何更改,仅此而已。

关于最终变量和匿名类,已经讨论了很多问题,例如这个。



 类似资料:
  • 我们使用apollo java客户端来使用graphQL服务,该服务在内部使用okhttp(3.12.11) 我们使用apollo客户端和okhttpclient的单例实例 我们面临的问题是上面的代码在多线程环境中运行,在可视化VM中,我可以看到okhttp只执行5个并行请求 我们没有使用aysnc功能。我们尝试了下面提到的方法,但没有一种有效 有人能告诉我如何提高okhttp中并行请求的限制吗?

  • 问题内容: 假设我有一个表,该表具有一个字段,该字段指示使用给定标记标记了多少个。 添加带有现有标签的新项目后,如何在SQLAlchemy中增加此计数器? 使用普通SQL,我将执行以下操作: 但是我如何用SQLAlchemy表达? 问题答案: 如果您有类似的东西: 您可以像这样增加字段: 或者,如果您有一些映射的模型,则可以选择编写: 这两个版本都将返回您要求的sql语句。但是,如果您不包括该列并

  • 问题内容: 我有一个正在处理的查询,我想增加一个字段并在键值不同时重新启动计数器。 我知道这段代码行不通。以编程方式,这就是我想要的… …最终结果看起来像这样: 是的,我坚持使用SQL2k。否则,该row_number()将起作用。 问题答案: 假设一个表: 在Microsoft SQL Server 2000中获得此权限的一种方法是使用子查询对具有相同ID和较低顺序的行进行计数。 提示: 现在是

  • 问题内容: 我有一个只有几行文字的标签,我想增加两行之间的间距。其他人也有类似的问题,但是解决方案不能解决我的问题。另外,我的标签可能包含也可能不包含段落。我是新来的。有使用情节提要的解决方案吗?还是只能通过其可能? 问题答案: 使用以下代码段将LineSpacing编程添加到您的代码中。 早期的Swift版本 迅捷4.0 斯威夫特4.2

  • 问题内容: 我想在特定日期添加一天。我怎样才能做到这一点? 现在,我想在这一天添加一天。 问题答案: 给定一个,你有几种可能性: 解决方案1:你可以为此使用类: 解决方案2:由于该类的各种缺点,你应该认真考虑使用库。使用,你可以执行以下操作: 解决方案3:使用Java 8,你还可以使用新的JSR 310 API(受Joda-Time启发):

  • 问题内容: 我有一个SQL查询为我提供X个结果,我希望查询输出中有一个叫做count的命令使查询变得像这样: 我怎样才能做到这一点? 问题答案: 好吧,我想这已经足够构成答案了:以下链接指定了两种方法:http : //www.techrepublic.com/blog/microsoft-office/an-access-query-that-returns- every-nth-记录/ 第一种