首页 文章

什么是默认此Collectors.toList以期望一个对象列表?

提问于
浏览
0

我们正在使用Java中的@Async注释和CompletableFutures来调用一些调用 . 我们有很多Pojo,我们正在异步调用中创建对象,但是在尝试将结果收集到List时,Eclipse希望我将Pojo列表更改为对象列表,而我不是了解它是否是从流中默认响应的CompletableFuture .

List<Pojo1> crudResponse = null;
List<Pojo1> listOfIterations =  new ArrayList<>();

//populates object with multiple entries in list
listOfIteration = populateIterationObject(param);

crudResponse = listOfIterations.stream()
    .map(str -> CompletableFuture.supplyAsync(() -> {
        try {
            return async.hitCrud(str);
            }catch(RequestProcessingException e){
                log.error(e);
            }
            return function;
        }))
        .map(CompletableFuture::join)
        .collect(Collectors.toList());
        }

//async class
    public CompletableFuture<Pojo1> hitCrud(Pojo1 iteration) throws RequestProcessingException {

        try {
            String response;
            Pojo1 pojoResponse;
            response = connectToCrud(iteration);

            if(response != null) {
                pojoResponse.add(response);
            }                       
        }catch(Exception ex){
            log.error(ex);
        }
        return CompletableFuture.completedFuture(pojoResponse);
    }

我点击方法返回Pojo1的对象,但是当我尝试使用Collectors.toList()创建一个列表时,我希望我有一个 <Object> 的List,我可以使用它,但需要更多的代码来拉出并转换每个响应我从异步调用中恢复 .

这是默认为Object的CompletableFuture吗?如果是这样,是否可以将其默认为Pojo1的类型?

编辑:我在IDE中看到的错误:

Type mismatch: cannot convert from List<Object> to List<Pojo1>

1 回答

  • 1

    Java推断的绑定类型与您想要的不同,因为您的代码是错误的 . 特定

    //异步类
    public CompletableFuture <Pojo1> hitCrud(Pojo1迭代)// ...

    List <Pojo1> crudResponse = null;
    List <Pojo1> listOfIterations = new ArrayList <>();

    ...,让我们分析一下这个流表达式:

    crudResponse = listOfIterations.stream()
    .map(str - > CompletableFuture.supplyAsync(() - > {
    尝试{
    return async.hitCrud(str);
    } catch(RequestProcessingException e){
    log.error(E);
    }
    返回功能;
    }))
    .MAP(CompletableFuture ::加入)
    .collect(Collectors.toList());

    • listOfIterations.stream() 产生 Stream<Pojo1>

    • 必须从参数推断出第一个 map() 方法调用的类型参数,作为外部lambda的返回类型 .

    • 外部lambda的返回类型本身必须从 CompletableFuture.supplyAsync() 调用的推断中推断出来,...

    • 本身就是内部lambda的返回类型 . 那么什么是返回类型?

    • 好吧,内部lambda可以返回调用 async.hitCrud(str) 的结果,一个 CompletableFuture<Pojo1>

    • 或它可以返回 function ,无论其类型是什么 .

    • 推断类型将是这两种类型中最近的共同祖先,很可能是 CompletableFuture<Pojo1>Object . 鉴于错误消息,它可能是 Object .

    • 所以你已经映射到 Stream<CompletableFuture<Object>> ,因此下一个映射产生 Stream<Object>

    • 将其收集到列表中会给出 List<Object> ,而不是 List<Pojo1> .

    That is not merely a cosmetic problem :列表可能真正包含不是 Pojo1 的对象 .

    要看到这一点,请考虑如果 function 类型为 CompletableFuture<Pojo1> ,分析将如何变化, hitCrud() 的返回值也是如此 . 然后内部lambda的返回类型将是 CompletableFuture<Pojo1> ,但这将使外部lambda CompletableFuture<CompletableFuture<Pojo1>> 的返回类型,最终给你一个 List<CompletableFuture<Pojo1>> ,这仍然不是你想要的 . 如果这实际上是你的情况,那么你可以通过消除外部lambda来解决问题,这样你只使用内部的映射 str

    crudResponse = listOfIterations.stream()
        .map(str -> {
                try {
                    return async.hitCrud(str);
                } catch(RequestProcessingException e) {
                    log.error(e);
                }
                return function;
            })
            .map(CompletableFuture::join)
            .collect(Collectors.toList());
    

相关问题