How to iterate over MultipartFile array using Java lambda and streams

筅森魡賤 提交于 2021-02-11 12:19:53

问题


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. 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;
  }

回答1:


 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. Note that here future.get() is a blocking call, which means these execute sequentially (and hence no need for ConcurrentHashMap).

If you are looking for parallel operations, you'll need to have a parallelStream. which can submit task and wait. In such case, you'll need to use Collectors.toConcurrentMap to collect the results. (Be very careful of the race conditions that may arise while merging the streams into single Map)



来源:https://stackoverflow.com/questions/65832967/how-to-iterate-over-multipartfile-array-using-java-lambda-and-streams

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!