【问题标题】:Intersecting List with keys of Map与 Map 的键相交的列表
【发布时间】:2020-04-20 09:25:17
【问题描述】:

我们有一张学生地图要记录Map<Student, StudentRecord>
学生班级如下:

Student {
    String id;
    String grade;
    Int age; 
}

此外,我们还提供了学生 ID (List<String>) 的列表。
使用 Java 流,过滤出其 ID 存在于提供的列表中的学生记录的最有效方法是什么?
预期的结果是映射到 Id(String) 的过滤列表 - <Map<Id, StudentRecord>>

【问题讨论】:

  • 如果输入是Map<Student,StudentRecord>,为什么输出是List<Map<Student,StudentRecord>>?输出不应该是Map<Student,StudentRecord>,其中一些条目被过滤掉了吗?
  • 而且无论如何,在找到“最有效的方法”之前,你应该先尝试找到“一种方法”。你试过什么吗?您面临的具体问题是什么?
  • 根据 Eran 的观察编辑了问题。从未尝试过使用 java 流进行交集。
  • 现在正是时候。提示:不要将其视为“十字路口”。把它想象成:我有一张地图,它是条目的集合,我只想要其中的一些。一旦我知道了我想要的,我想把它们存储在另一张地图中。

标签: java string list java-8 java-stream


【解决方案1】:

虽然其他答案是正确的,但我认为它们效率不高,因为它们使用临时内存或其同谋不是o(n)

另一个答案是这样的:

provided.stream()
        .map(id -> new AbstractMap.SimpleEntry<>(id, map.entrySet()
                    .stream().filter(st -> st.getKey().id == id)
                    .map(Map.Entry::getValue).findFirst()))
        .filter(simpleEntry ->simpleEntry.getValue().isPresent())
        .map(entry-> new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue().get()))
        .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue)) 

【讨论】:

    【解决方案2】:

    首先,我会将您的 List 转换为 Set,以避免线性搜索时间:

    List<String> ids = ...
    Set<String> idsSet = new HashSet<>(ids);
    

    现在,您可以流式传输 Map 的条目,过滤掉 List/Set 中具有 id 的条目,并将剩余的条目收集到输出 Map

    Map<String,StudentRecord> filtered = 
        input.entrySet()
             .stream()
             .filter(e -> !idsSet.contains(e.getKey().getId()))
             .collect(Collectors.toMap(e -> e.getKey().getId(),Map.Entry::getValue));
    

    【讨论】:

      【解决方案3】:

      您可以流式传输一组条目:

      map.entrySet().stream()
          .filter(e -> list.contains(e.getKey()))
          .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
      

      如果您还想将键映射到id 字段,那么:

      map.entrySet().stream()
          .filter(e -> list.contains(e.getKey()))
          .collect(toMap(e -> e.getKey().getId(), Map.Entry::getValue));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-03
        • 2022-06-20
        • 1970-01-01
        • 1970-01-01
        • 2010-11-27
        • 2019-03-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多