【问题标题】:Java 8 stream filter for Map<String, List<Object>>Map<String, List<Object>> 的 Java 8 流过滤器
【发布时间】:2021-09-03 00:36:33
【问题描述】:

我在尝试使用流处理地图时遇到问题。 我有:

Class Person {
  public String name;
  public String ID;
}

还有 2 个不同的地图(结构相同但包含不同的元素):

Map<String, List<Person>> map1 = new HashMap<>();
map1.put("group1", new Person("abc", "12345"));
map1.put("group2", new Person("def", "23456"));

Map<String, List<Person>> map2 = new HashMap<>();
map2.put("group3", new Person("asd", "12345"));

我想要做的是使用流来处理这两个地图,并过滤掉 Map 只满足我给定条件的,例如如果 Person 具有相同的 ID,则将其合并并保留名字。 对于上面的例子,结果应该是:

{group1,("abc", "12345")}
{group2,("def", "23456")}

这是我当前的实现:

Map<String, List<Person>> result = map1.entrySet()
                .stream()
                .filter(x -> x.getValue().stream().allMatch(e -> e.getID() !=
                        map2.entrySet().stream().flatMap(it -> it.getValue().stream().forEach(y -> y.getID()))))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

我对 Stream 不熟悉,不胜感激。

谢谢

【问题讨论】:

  • 您的地图是人员列表的 ID,但是您将一个人放入其中。数据结构到底是什么?
  • 那不是ID,只是组名
  • map1 中,您对同一张地图使用相同的密钥,但对不同的人使用。值类型为List&lt;Person&gt;。您需要在要求之前和之后显示您的确切要求。如果您不熟悉流,为什么不使用其他方法。
  • 没有流我需要使用循环来处理这两个地图,你猜这很耗时?我想要做的是合并这两个地图,并确保合并后我没有具有相同 ID 的人
  • @HaoR 在您将map1 定义为Map&lt;String, List&lt;Person&gt;&gt; 的问题中。但是map1.put("group1", new Person("abc", "12345"));这个语句只有在你的地图是Map&lt;String, Person&gt;时才会编译

标签: java filter java-8 java-stream


【解决方案1】:

你是否在追求类似以下的事情?

    Map<String, List<Person>> map1 = new HashMap<>();
    map1.put("group1", new ArrayList<>(List.of(new Person("abc", "12345"))));
    map1.put("group2", new ArrayList<>(List.of(new Person("def", "23456"))));

    Map<String, List<Person>> map2 = new HashMap<>();
    map2.put("group3", new ArrayList<>(List.of(new Person("asd", "12345"))));

    Map<String, List<Person>> mergedMap = new HashMap<>(map1);
    for (Entry<String, List<Person>> entry : map2.entrySet()) {
        for (Person p2 : entry.getValue()) {
            boolean sameIdFound = map1.entrySet()
                    .stream()
                    .anyMatch(e1 -> e1.getValue().stream().anyMatch(p1 -> p1.getId().equals(p2.getId())));
            if (! sameIdFound) {
                mergedMap.computeIfAbsent(entry.getKey(), k -> new ArrayList<>())
                        .add(p2);
            }
        }
    }
    
    mergedMap.forEach((g, pl) -> System.out.println(g + " -> " + pl));

输出:

group2 -> [23456=def]
group1 -> [12345=abc]

我首先创建一个与map1 相同的新地图(浅拷贝,你可能想要更深的拷贝,暂时留给你)。接下来对于map2 中的每个人,我检查map1 中是否已经存在具有相同ID 的人。如果没有,我将其与map2 中的组和名称一起插入。

【讨论】:

    猜你喜欢
    • 2022-01-17
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多