使用AtomicInteger在Stream中建立索引是否合法?
我想得到一个答案,指出为什么以下在一个非常简单的示例上描述的想法通常被认为是不好的并且知道它的缺点的原因。
我有一句话,我的目标是使每一秒都变成大写。对于这两种情况,我的出发点是完全相同的:
String sentence = "Hi, this is just a simple short sentence";String[] split = sentence.split(" ");
在 传统 和程序的做法是:
StringBuilder stringBuilder = new StringBuilder();for (int i=0; i<split.length; i++) {
if (i%2==0) {
stringBuilder.append(split[i]);
} else {
stringBuilder.append(split[i].toUpperCase());
}
if (i<split.length-1) { stringBuilder.append(" "); }
}
当要使用java-stream时,由于在lambda表达式中使用了有效的最终变量或最终变量约束,因此使用受到限制。我必须使用数组及其第一个也是唯一索引的解决方法,这是我的问题“
如何在Java
Stream中增加值”的第一个注释中建议的。这是示例:
int index[] = {0};String result = Arrays.stream(split)
.map(i -> index[0]++%2==0 ? i : i.toUpperCase())
.collect(Collectors.joining(" "));
是的,这是一个糟糕的解决方案,在我找不到的问题的注释中,我听到了一些很好的理由(如果您提醒我一些问题,如果可能,我会两次投票)。但是,如果我使用该方法AtomicInteger
-有什么区别吗?与前一种方法相比,它是一种没有副作用的好又安全的方法吗?
AtomicInteger atom = new AtomicInteger(0);String result = Arrays.stream(split)
.map(i -> atom.getAndIncrement()%2==0 ? i : i.toUpperCase())
.collect(Collectors.joining(" "));
不管它看起来多么丑陋,我都要求描述可能的弱点及其原因。我不在乎性能,但在意第二种解决方案的设计和可能的弱点。
请不要将AtomicInteger与多线程问题匹配。我使用该类是因为它以本例所需要的方式接收,递增和存储值。
正如我在回答中经常说的那样, “ Java Stream-API”
并不是万能的。我的目标是探索并找出这句话的适用范围,因为与StringBuilder
的代码段相比,我发现最后一个代码段非常清晰,可读且简短。
编辑:在使用Stream-API进行迭代时需要同时使用项目和索引时,是否存在任何适用于上述摘录以及所有问题的替代方法?
回答:
该软件包的文档java.util.stream
指出:
通常,不鼓励行为参数对流操作的副作用,因为它们经常会导致无意识地违反无状态要求以及其他线程安全危害。
[…]
副作用的顺序可能令人惊讶。即使将管道约束为产生与流源的遇到顺序一致的结果(例如,
IntStream.range(0,5).parallel().map(x
-> x*2).toArray()必须产生
[0, 2, 4, 6,
8]),也无法保证将mapper函数应用于单个元素的顺序或给指定元素执行任何行为参数的线程。
这意味着可能会无序地处理元素,因此Stream
-solutions可能会产生错误的结果。
这(至少对我而言)是针对您的两个Stream
解决方案的致命论点。
通过消除的过程,我们只剩下“传统解决方案”了。老实说,我认为此解决方案没有任何问题。如果要摆脱for
-loop,可以使用foreach
-loop
重写此代码:
boolean toUpper = false; // 1st String is not capitalizedfor (String word : splits) {
stringBuilder.append(toUpper ? word.toUpperCase() : word);
toUpper = !toUpper;
}
要获得简化的(据我所知)正确的解决方案,请查看Octavian
R.的答案。
您的问题。“流量限制”是基于意见的。
问题的答案到此结束。其余的是我的观点,应视为这样。
在Octavian
R.的解决方案中,通过创建了一个人工索引集IntStream
,然后将其用于访问String[]
。对我来说,这比简单的for
-或-
foreach
循环具有更高的认知复杂度,在这种情况下,我认为使用流而不是循环没有任何好处。
以上是 使用AtomicInteger在Stream中建立索引是否合法? 的全部内容, 来源链接: utcz.com/qa/418491.html