【问题标题】:Modify local list in parallel stream java修改并行流java中的本地列表
【发布时间】:2021-10-19 04:55:22
【问题描述】:

我有一个方法如下:

  public void method ()
  {
        List<String> list1 = someOperation();
        List<List2Class> list2;
        long failedCount = 0;
        for (String element : list1) {
            try {
                list2 = someclass.method1(element);
                list2 = someclass.method2(element);
                someclass.saveToDB(list2);
            
            } catch (Exception e) {
                failedCount++;
              
            }
        }
       //some checks on failedCount
    }

我想将 for 循环转换为并行流,有人可以告诉我上述方法中的代码更改应该是什么吗? PS - method1 和 method2 正在返回 list2 的修改版本。

【问题讨论】:

  • 看起来list2 只是someclass.method2(/* last element of list1 */) 那里。你真的需要处理所有其他的吗?
  • @AndyTurner 如果没有try ... catch,那将是正确的。对于try catch,它可以是任何东西。更具体地说,最后没有失败。我怀疑这里是否有可能以任何有意义的方式使用 Streams。
  • 我已将问题更新为更具体,每个方法都返回 list2 的修改版本,该版本将针对 for 循环中的每个元素保存到 db
  • 从未使用过someclass.method1(element) 的结果。它被下一行someclass.method2(element) 的结果覆盖。

标签: java java-8 stream parallelstream


【解决方案1】:

这里的逻辑基本上是“最后一次成功操作的结果”。

假设您不需要failedCount(您没有显示它正在使用),您可以这样做:将成功的操作映射到当前的Optional,将失败的操作映射到缺席的Optional;并且只选择最后一个现在:

Optional<List<List2Class>> opt = list1.stream()
    .flatMap(element -> Stream.of(runOperation(someclass::method1, element), runOperation(someclass::method2, element))
    .reduce((a, b) -> !b.isPresent() ? a : b);

runOperation 类似于:

Optional<List<List2Class>> runOperation(Function<String, List<List2Class>> operation, String parameter) {
  try {
    return Optional.of(operation.apply(parameter));
  } catch (Exception e) {
    return Optional.absent();
  }
}

然后您需要决定如果没有操作成功,list2 应该具有什么值。

如果您确实需要failedCount,您可以将其拆分一下:

Stream<Optional<List<List2Class>>> intermediate =
    list1.stream()
        .flatMap(element -> Stream.of(runOperation(someclass::method1, element), runOperation(someclass::method2, element));

Map<Boolean, List<Optional<List<List2Class>>>> partitioned =
    intermediate.collect(Collectors.partitioningBy(Optional::isPresent));

现在partitioned.get(true) 拥有所有成功的结果,而partitioned.get(false) 拥有所有失败的结果。所以:

Optional<List<List2Class>> opt = partitioned.get(true).stream().reduce((a, b) -> !b.isPresent() ? a : b);
long failedCount = partitioned.get(false).size();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-30
    • 2020-07-22
    • 2015-08-15
    • 2016-11-24
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多