简体   繁体   English

如何使用 Java lambda 和流迭代 MultipartFile 数组

[英]How to iterate over MultipartFile array using Java lambda and streams

Below is my code to upload some file attachments to external storage.下面是我将一些文件附件上传到外部存储的代码。 I would like to know if there is a way to avoid for loop in the below method to iterate over the MultipartFile[] array so that everything will be done using the java streams and lambda functions.我想知道是否有一种方法可以避免以下方法中的 for 循环来迭代 MultipartFile[] 数组,以便使用 java 流和 lambda 函数完成所有操作。 Would like to have any better way to achieve the below希望有更好的方法来实现以下目标

public void uploadMyFiles(MultipartFile[] multipartFiles, String path) throws Exception {
    ConcurrentHashMap<String, String> sMap = new ConcurrentHashMap<>();
    ExecutorService myExecutor = Executors.newFixedThreadPool(5);
    for (MultipartFile multipartFile : multipartFiles) {
        CompletableFuture<String> future = CompletableFuture
                .supplyAsync(() -> uploadMyFile(multipartFile, path), myExecutor );
        String status = future.get(10, TimeUnit.SECONDS);
        sMap.put(multipartFile.getOriginalFilename(), status);
    }
}

  private String uploadMyFile(MultipartFile file, String fpath){
    return null;
  }
 private static Map<String, String> retrieveCompletableFuture(
      CompletableFuture<Map<String, String>> futureMap) {
    try {
      return futureMap.get(10, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
      e.printStackTrace();
    }
    return null;
  }

  public void uploadMyFiles(MultipartFile[] multipartFiles) throws Exception {
    ExecutorService executor = Executors.newFixedThreadPool(5);

    String s3Path = "/demo-mypath/";

    ExecutorService myExecutor = Executors.newFixedThreadPool(5);
    Arrays.stream(multipartFiles)
        .map(
            multipartFile ->
                CompletableFuture.supplyAsync(() -> uploadMyFile(multipartFile, s3Path), executor))
        .map(cfuture -> retrieveCompletableFuture(cfuture))
        .map(Map::entrySet)
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

  }

I've exactly made your implementation to lambdas.我已经将您的实现完全实现为 lambdas。 Note that here future.get() is a blocking call, which means these execute sequentially (and hence no need for ConcurrentHashMap).请注意,这里的 future.get() 是一个阻塞调用,这意味着它们是按顺序执行的(因此不需要 ConcurrentHashMap)。

If you are looking for parallel operations, you'll need to have a parallelStream.如果您正在寻找并行操作,则需要一个 parallelStream。 which can submit task and wait.可以提交任务并等待。 In such case, you'll need to use Collectors.toConcurrentMap to collect the results.在这种情况下,您需要使用 Collectors.toConcurrentMap 来收集结果。 (Be very careful of the race conditions that may arise while merging the streams into single Map) (在将流合并到单个 Map 时要非常小心可能出现的竞争条件)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM