【问题标题】:Create arraylist from list of maps for certain key value with java 8使用java 8从映射列表中为某些键值创建arraylist
【发布时间】:2020-09-07 11:05:09
【问题描述】:

我有一个带有地图列表的对象。每张地图如下所示:

{
  id: "something",
  link: "someLink"
}

我正在尝试创建地图中所有 id 的数组列表。我可以用一个简单的循环来做到这一点

 List<String> Ids = new ArrayList<>();
        
 List<Map<String, String>> maps = pojo.getMaps();
        
 for(Map<String, String> map: maps) {
       Ids.add(map.get("id"));
    }

但是这是如何使用 java 8 流在一行中完成的呢?我从来没有在地图上使用过它,所以我迷路了。 我认为它会是这样的,但老实说我不知道​​

List<String> ids = pojo.getMaps().stream().map(Map.Entry::  ???? ).collect(Collectors.toList())

【问题讨论】:

  • 这应该可以解决问题:.map(m -&gt; m.get("id")).collect(Collectors.toList());

标签: java hashmap java-stream


【解决方案1】:

pojo.getMaps().stream()

到目前为止,一切都很好。您现在有一个 Map&lt;String, String&gt; 对象流。我们只需要从中获取密钥。那么,鉴于您的一个奇怪的地图事物,我们如何将其转化为键值?

看起来像一个微不足道的map.get("id") 可以完成这项工作,不是吗?

让我们把它放在 lambda 中:

pojo.getMaps().stream().map(theMap -&gt; theMap.get("id"))

现在我们有了一个带有 ID 的 Stream&lt;String&gt;

但是,请注意!

您从一个看起来像对象的地图对象开始这一事实是一种巨大的代码气味。很可能您应该在项目中返回几个步骤并修复它。你真的应该有一个代表这个链接概念的类:

@Value
public class Link {
    String id, link;
}

然后从那里出发:

listOfLinks.stream().map(Link::getId).distinct().collect(...);

注意:以上使用Lombok's @Value

功能只是一个工具

请注意,无需重写代码以“使用 java 8 功能”。比较:

    var ids = pojo.getMaps().stream()
      .map(m -> m.get("id"))
      .collect(Collectors.toList());

与:

    var ids = new ArrayList<String>();
    for (var m : pojo.getMaps()) ids.add(m.get("id"));

代码量差不多。

【讨论】:

  • 感谢您的解释和建议
【解决方案2】:

您可以在循环中使用相同的方式从映射中获取id 的值。这里.map()用于将Map&lt;String, String&gt;转换为String表示将Map转换为键id的值

List<String> ids = pojo.getMaps().stream()                 // Stream<Map<String, String>>
                                 .map(e -> e.get("id"))    // Stream<String> 
                                 .collect(Collectors.toList());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 2013-03-15
    • 1970-01-01
    相关资源
    最近更新 更多