如何将Lambda返回的Optional<? extends OnlineResource>转为Optional<OnlineResource>
解决方案
要把Optional<? extends OnlineResource>转换成Optional<OnlineResource>,有几种简单直接的方式,根据你的代码场景可以任选:
方法1:使用map做向上转型
因为? extends OnlineResource的实例本身就是OnlineResource的子类,向上转型是安全的,直接在流末尾加一个map转换即可:
Optional<OnlineResource> onlineResourceOptional = metadata.getDistributionInfo().stream() .filter(Objects::nonNull) .flatMap(distribution -> distribution.getTransferOptions().stream()) .filter(Objects::nonNull) .flatMap(digitalTransferOptions -> digitalTransferOptions.getOnLines().stream()) .filter(Objects::nonNull) .filter(onlineResource -> onlineResource.getProtocol().equals("OGC:STA")) .map(OnlineResource.class::cast) // 这里做类型转换 .findFirst();
或者用更简洁的Lambda写法:.map(r -> (OnlineResource) r),效果完全一样。
方法2:显式指定flatMap的泛型类型
如果digitalTransferOptions.getOnLines()返回的是List<? extends OnlineResource>,你可以在调用getOnLines()时显式指定泛型为OnlineResource,这样流的元素类型直接就是OnlineResource,不需要后续转换:
Optional<OnlineResource> onlineResourceOptional = metadata.getDistributionInfo().stream() .filter(Objects::nonNull) .flatMap(distribution -> distribution.getTransferOptions().stream()) .filter(Objects::nonNull) .flatMap(digitalTransferOptions -> digitalTransferOptions.<OnlineResource>getOnLines().stream()) // 显式指定泛型 .filter(Objects::nonNull) .filter(onlineResource -> onlineResource.getProtocol().equals("OGC:STA")) .findFirst();
这种方式的好处是不需要额外的转换步骤,直接从源头修正流的元素类型。
方法3:先过滤类型再转换(可选)
如果你的场景中存在非OnlineResource的子类实例(虽然根据业务逻辑可能不存在),可以先过滤再转换,确保类型安全:
Optional<OnlineResource> onlineResourceOptional = metadata.getDistributionInfo().stream() .filter(Objects::nonNull) .flatMap(distribution -> distribution.getTransferOptions().stream()) .filter(Objects::nonNull) .flatMap(digitalTransferOptions -> digitalTransferOptions.getOnLines().stream()) .filter(Objects::nonNull) .filter(OnlineResource.class::isInstance) // 先过滤类型 .filter(onlineResource -> onlineResource.getProtocol().equals("OGC:STA")) .map(OnlineResource.class::cast) .findFirst();
不过在你的业务场景里,既然getOnLines()返回的是? extends OnlineResource的集合,向上转型本身就是安全的,所以前两种方法足够使用。
内容的提问来源于stack exchange,提问作者charlycou
相关产品推荐
相关产品推荐

