删除 Map<Long, List<Object>> 的条目

经过数小时的研究,我找不到问题的解决方案。我有一个Map<String, List<User>>,我想根据列表中的某些值删除地图的某些项目。


我必须关注用户类


public class User {

    public String firstName,

    public Integer age


    public boolean is50() {

       return this.age.equals(50);

    }


}

我有一个这样的地图:


Map<String, List<User> myMap = new HashMap<>();


myMap.put("A", new ArrayList<>());

myMap.get("A").add(new User("John", 50));

myMap.get("A").add(new User("Bob", 30));


myMap.put("B", new ArrayList<>());

myMap.get("B").add(new User("Sam", 25));

myMap.get("B").add(new User("Sarah", 56));


myMap.put("C", new ArrayList<>());

myMap.get("C").add(new User("Gill", 15));

myMap.get("C").add(new User("Jim", 20));

现在,如果列表中至少有一个用户年龄为 50 岁,我想删除 Map 的条目。另外,我想使用 Java 8 功能来实现这一点。


我发现有一个removeIf函数,但我不能让它与列表一起使用。


我试过这样的事情:


Map<String, List<User> filteredMap = myMap

                                 .enrySet()

                                 .removeIf(e -> e.getValue()

                                        .stream()

                                        .filter(user -> user::is50)

                                        .collect(Collectors.toList())

当然那是行不通的:(


例外的输出是一个 filteredMap,所有用户只有 B 和 C 键(必须删除 A 键,因为 John 已经 50 岁了)


谢谢你的帮助,希望它是清楚的;)


青春有我
浏览 160回答 4
4回答

红糖糍粑

这应该可以解决问题:myMap.entrySet()     .removeIf(e -> e.getValue()         .stream()         .anyMatch(User::is50));请注意,entrySet() 修改 (removeIf) 会影响条目集支持的映射。因此,您要么必须制作地图的副本并在副本上运行它,要么让第一个地图 ( myMap) 被修改。至于制作地图副本,您可以简单地执行以下操作:Map<String, List<User>> copy = new HashMap<>(myMap);就地删除的更好方法如下:myMap.values()     .removeIf(v -> v.stream()         .anyMatch(User::is50));这更好的原因有四个:getValue您可以取消对since 的调用,因为values它直接提供了值集。values它更清楚地传达意图 -与价值之间的逻辑跳跃比entrySet与价值之间的逻辑跳跃更少。它更简洁并且不是反模式(例如,使用peekoutside of debugging 是一种反模式,尽管有时更简洁)。它仍然有效,因为返回的 Collection由 mapvalues支持。

德玛西亚99

只需用于Stream::noneMatch您的嵌套 Stream :Map<String, List<User>> filteredMap = myMap.entrySet()                 .stream()                 .filter(e -> e.getValue()                         .stream()                         .noneMatch(User::is50)                 )                 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); filteredMap.forEach((key, value) -> System.out.println(key));输出是:B C在此解决方案myMap中将不受影响,因为我stream用完了entrySet然后收集了它。Set::removeIf会改变你以前的地图,因为支持你原来的条目的Map::entrySet返回。SetMap

汪汪一只猫

如您所见,您必须对 EntrySet 进行操作。您可以将其转换为流并收集回新地图,如下所示:myMap.entrySet().stream() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(e&nbsp;->&nbsp;e.getValue().stream().noneMatch(User::is50)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toMap(Map.Entry::getKey,&nbsp;Map.Entry::getValue))

明月笑刀无情

您可以使用 Map EntrySet 来解析您的地图,然后解析每个条目中的列表for (Map.Entry<String, List<User> entry : myMap.entrySet()){&nbsp; &nbsp; boolean toDelete = false;&nbsp; &nbsp; for (User user : entry.getValue())&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (user.age == 50)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; toDelete = true;&nbsp; &nbsp; }&nbsp; &nbsp; if (toDelete)&nbsp; &nbsp; &nbsp; &nbsp; myMap.remove(entry.getKey());}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java