【问题标题】:Lambda function that instantiates an object实例化对象的 Lambda 函数
【发布时间】:2016-11-12 04:03:25
【问题描述】:

我正在尝试将列表转换为地图,键是列表的每个元素,值是新的 ArrayList。

目前我正在这样做:

List<String> strLst = ...
Map<String, List<Foo>> map = strLst.stream()
             .collect(Collectors.toMap(Function.identity(), _unused -> new ArrayList<>()));

有没有比这样做更好的方法:_unused -&gt; new ArrayList&lt;&gt;()


为了澄清我的用例: 我有一个 API,它接收资源 ID 列表(即上面示例中的 List&lt;String&gt; strLst),我需要获取与每个资源 ID 关联的资源列表(它是一对多映射)。它需要返回一个映射,其中映射的键集具有所有资源 Id。如果资源没有映射,则每个资源 ID 的值都是一个空列表。 (但我希望 map.keySet 等同于原始列表)

我做不到

for (String resourceId : allResourceIds) {
  List<Result> results = getResults(resourceId);
  map.put (resourceId, results)
}

因为出于性能原因我需要调用批量 API

Map<String, List<Result>> map = ... // this is the step i'm trying to implement
List<Result> allResults = bulkGetResults(allResourceIds)
for (Result res : allResults) {
  map.get(res.getResourceId()).add(res)
}

【问题讨论】:

  • 如果数组列表有一个构造函数参数(使用起来很有意义)_unused 那么你可以做ArrayList::new 但除此之外不是真的。虽然为什么将元素映射到一个空列表,而不是说Collectors#groupingBy
  • 我会看看这个地图是怎么用的,很可能你不需要这一步。
  • 补充说明

标签: java lambda java-stream


【解决方案1】:

看起来您首先要使用空值的 ArrayList 启动一个空 Map,然后用批量调用的结果填充它。

根据您的情况,您可以将这些步骤组合如下:

Map<String, List<Result>> results = allResults.stream().collect(Collectors.groupingBy(Result::getResourceId));

如果您只对批量获取返回的资源感兴趣,那么应该这样做。如果您在没有结果时确实需要一个空列表,您可以稍后将其作为一个单独的问题解决,例如

public List<Result> getResult(String resourceId){
    List<Result> resources = results.get(resourceId);
    return resources != null ? resources : Collections.emptyList();
}

【讨论】:

  • 谢谢,第一个解决方案很好,但我确实需要为没有结果的键返回空列表。然而,第二种解决方案需要将结果包装在一个类中,而不是直接返回地图。
  • 如果你需要它并且你不想换行,我认为没有太多其他选择了。之后您可以通过流式传输 id 来添加空列表,过滤掉那些具有空值的列表,然后 foreach 缺少一个使用 Collections::emptyList () 添加一个空列表,但我不知道这是否比您的第一个解决方案更干净.在我的手机上,所以现在无法编码,对不起。
【解决方案2】:

您可能希望先创建资源映射,然后再填写缺少的 resourceId:

Map<String, List<Result>> resultMap = bulkGetResults(allResourceIds).stream()
                            .collect(groupingBy(Result::getResourceId));

strLst.stream().forEach(id -> resultMap.putIfAbsent(id, new ArrayList<>()));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2022-06-19
    • 2010-11-07
    • 1970-01-01
    相关资源
    最近更新 更多