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

由于RaceCondition,使用流迭代LinkedList正在更改结果列表

慕容康安
2023-03-14

我们在java8中使用Streams迭代LinkedList,并创建另一个列表。但是由于竞争条件,结果列表的大小超出了限制。

List<DesInfo> InfoList = new LinkedList<>();
documentList.stream()
            .parallel()
            .forEach(document -> {
                Info descriptiveInfo = objectFactory.createDescriptiveInfo();
                List<Document> documents = new ArrayList<>();
                documents.add(document);
                descriptiveInfo.setHotelInfo(getHotelInfo(document.get(CODE), documents));
                InfoList.add(Info);
            });

如果我们每次都运行此代码,我们都会看到为相同的documentList输入生成不同大小的InfoList。我浏览了一些论坛,他们提到LinkedList不是线程安全的,而是任何线程安全的集合。但我的要求不允许我离开LinkedList。我需要在相同的LinkedList中使用并行流功能。

谢谢,拉格万

共有2个答案

万俟招
2023-03-14

使用集合而不是更改集合的状态。

首先创建一个映射函数:

private DesInfo documentToDesInfo(Document document){
    DesInfo info = objectFactory.createDescriptiveInfo();
    List<Document> documents = new ArrayList<>();
    documents.add(document);
    info.setHotelInfo(getHotelInfo(document.get(CODE), documents));
    return info;
}

然后在您的管道中使用它:

List<DesInfo> infoList = documentList.parallelStream()
                                     .map(this::documentToDesInfo)
                                     .collect(toCollection(LinkedList::new));
穆招
2023-03-14

不要使用for每一个,而是使用集合器map()操作:

List<HotelDescriptiveInfo> hotelDescriptiveInfoList = documentList.parallelStream()
    .map(document -> {
        HotelDescriptiveInfo descriptiveInfo = objectFactory.createHotelDescriptiveInfo();
        List<Document> documents = new ArrayList<>();
        documents.add(document);
        descriptiveInfo.setHotelInfo(getHotelInfo(document.get(HOTEL_CODE), documents));
        return descriptiveInfo;
    })
    .collect(Collectors.toCollection(LinkedList::new));

< code>Stream api将负责处理,不允许出现竞争情况。

 类似资料:
  • 问题内容: List rateList = guestList.stream() .map(guest -> buildRate(ageRate, guestRate, guest)) .collect(Collectors.toList()); 在上面的代码中,可以通过内部方法的索引。我在构建时还需要传递索引,但无法通过获取索引。 问题答案: 您尚未提供的签名,但是我假设您希望首先传递元素的索引

  • 我有一个映射,它包含日期作为键和(另一个字符串作为键和列表作为值的映射)作为值。,我想填充另一个将String作为键和double作为值的映射。FlexiServer的内容包括 因此,基本上,我想首先迭代外部映射以获得内部映射,然后迭代内部映射以获得FlexiServers列表,并填充新的映射,其中服务器号作为键,数量列表作为值。我如何使用Java8流来实现这一点呢? 我尝试使用for循环,但我希

  • 问题内容: 假设我有以下几种类型: 我想迭代节点的属性以更改它们。 我本来希望能够做到: 但是由于不是指针,所以这行不通,我必须这样做: 有没有更简单或更快速的方法?是否可以直接从中获取指针? 显然,我不想仅仅为了迭代而更改结构,更冗长的解决方案不是解决方案。 问题答案: 不,您想要的缩写是不可能的。 原因是从您要遍历的切片中复制值。关于范围的规范说: value (if 2nd variable

  • 问题内容: 我在工作中使用的程序使用Python作为脚本语言。我试图在插入列表时修改列表感到困惑。另外,我在for循环中有一些逻辑,希望将列表的一部分从浮点数转换为文本。最后,所有文本必须正好为4个空格。在我为解决这个问题而进行的研究中,我遇到了许多其他的模拟问题,这些其他问题试图在迭代列表时尝试修改列表。但是我觉得我的问题很独特,因为我试图在遍历列表时将列表从浮点数修改为文本。 我实际上找到了解

  • 我想在字符串与给定值匹配时更新该值 有没有人可以使用Java streams API来实现上述功能

  • 问题内容: 我知道您不应在遍历列表时添加/删除项目。但是,如果不更改列表长度,是否可以修改要迭代的列表中的项目? 还是应该迭代列表索引?像那样: 问题是:以上两种方式都是允许的,还是只有第二种是没有错误的? 如果答案是肯定的,以下代码段是否有效? UPD。我想在python文档中看到“允许这些操作”而不是某人的假设。 问题答案: 可以这么说,您 不是在 修改列表。您只是在修改列表中的元素。我不认为