gpt4 book ai didi

java - Steam操作修改实际列表

转载 作者:行者123 更新时间:2023-12-01 19:39:13 25 4
gpt4 key购买 nike

我在某处读到,流操作总是在终端操作返回一个新集合,并且不会更改应用了流操作的原始集合。

但就我而言,原始列表已被修改。

 return subscriptions.stream()
.filter(alertPrefSubscriptionsBO -> (alertPrefSubscriptionsBO.getType() == AlertPrefContactTypeEnum.PRIMARY_CONTACT || alertPrefSubscriptionsBO.getType() == AlertPrefContactTypeEnum.SECONDARY_CONTACT))
.map(alertPrefSubscriptionsBO -> {
if (alertPrefSubscriptionsBO.getType() == AlertPrefContactTypeEnum.PRIMARY_CONTACT) {
alertPrefSubscriptionsBO.setType(AlertPrefContactTypeEnum.PRIMARY);
} else
alertPrefSubscriptionsBO.setType(AlertPrefContactTypeEnum.SECONDARY);

return alertPrefSubscriptionsBO;
})
.collect(groupingBy(AlertPrefSubscriptionsBO::isActiveStatus, groupingBy(AlertPrefSubscriptionsBO::getAlertLabel, Collectors.mapping((AlertPrefSubscriptionsBO o) -> o.getType()
.getContactId(), toSet())
)));

此操作后,订阅列表已被修改,仅包含 AlertPrefContactTypeEnum.PRIMARY 和 AlertPrefContactTypeEnum.SECONDARY 对象。我的意思是列表的大小保持不变,但值发生了变化。

最佳答案

那是因为您违反了 map(Function<? super T,? extends R> mapper) 的契约(Contract)方法:

Parameters:
mapper - a non-interfering, stateless function to apply to each element

您违反了“无状态”部分:

Stateless behaviors

Stream pipeline results may be nondeterministic or incorrect if the behavioral parameters to the stream operations are stateful. A stateful lambda (or other object implementing the appropriate functional interface) is one whose result depends on any state which might change during the execution of the stream pipeline. An example of a stateful lambda is the parameter to map() in:

Set<Integer> seen = Collections.synchronizedSet(new HashSet<>());
stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...

Here, if the mapping operation is performed in parallel, the results for the same input could vary from run to run, due to thread scheduling differences, whereas, with a stateless lambda expression the results would always be the same.

Note also that attempting to access mutable state from behavioral parameters presents you with a bad choice with respect to safety and performance; if you do not synchronize access to that state, you have a data race and therefore your code is broken, but if you do synchronize access to that state, you risk having contention undermine the parallelism you are seeking to benefit from. The best approach is to avoid stateful behavioral parameters to stream operations entirely; there is usually a way to restructure the stream pipeline to avoid statefulness.

实现该映射操作的正确方法是复制 alertPrefSubscriptionsBO并为副本指定一个新类型。

遵循 java.time 使用的样式类,例如查看所有 withXxx(...) ZonedDateTime的方法,您将制作或处理 alertPrefSubscriptionsBO对象是不可变的,并且具有获取属性已更改的副本的方法,例如使用方法withType(...)在类上并使用 AlertPrefContactTypeEnum 的静态导入枚举,您的代码可能是:

.map(bo -> bo.withType(bo.getType() == PRIMARY_CONTACT ? PRIMARY : SECONDARY))

关于java - Steam操作修改实际列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55957938/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com