如何在Java中通过键的列表过滤地图

53 阅读2分钟

学习在Java 8中使用forEach()循环和Stream.filter()API按键或值过滤Map

1.设置

在代码示例中,我们将使用下面的用户地图地图的键是整数类型,而地图的值是用户实例。

Map<Integer, User> usersMap = Map.of(
    1, new User(1, "Alex"),
    2, new User(2, "Allen"),
    3, new User(3, "Brian"),
    4, new User(4, "Bob"),
    5, new User(5, "Charles"),
    6, new User(6, "David"),
    8, new User(7, "Don"),
    9, new User(8, "Dave"));

我们将根据以下列表的键值过滤地图。这个列表可以包含任何东西。我们将存储用户的ID,以使例子易于理解。

List<Integer> idList = List.of(1,3,5,7);

2.通过键列表过滤地图

假设我们有一个用户id列表,我们想得到由id出现在列表中的用户组成的子图

要做到这一点,我们将遍历地图EntrySet。然后我们将在filter()函数中检查id是否存在于List中。最后,我们将使用Collectors.toUnmodifiableMap()将匹配的条目集收集到一个新的Map中。

Map<Integer, User> filteredMap = usersMap.entrySet()
    .stream()
    .filter(entry -> idList.contains(entry.getKey()))
    .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));

System.out.println(filteredMap);

程序的输出。

{1=User(id=1, name=Alex), 3=User(id=3, name=Brian), 5=User(id=5, name=Charles), 7=User(id=7, name=Don)}

如果我们想改变评价标准,那么我们需要改变filter()函数中的表达式。例如,如果我们想在列表中检查用户的ID,那么将*filter()*的表达式改为如下。

...
.filter(entry -> idList.contains(entry.getValue().getId()))
...

3.过滤地图并将值收集到一个列表

另一个用例是,我们想过滤地图,并将键值存在于List中的入口集的值收集到List中。

List<User> usersList = usersMap.values()
    .stream()
    .filter(user -> idList.contains(user.getId()))
    .collect(Collectors.toUnmodifiableList());

System.out.println(usersList);

该程序的输出。

[User(id=1, name=Alex), User(id=3, name=Brian), User(id=5, name=Charles), User(id=7, name=Don)]

4.使用forEach()过滤地图

我们也可以使用forEach()循环来过滤Map。forEach循环接受一个Consumer动作,接受一个输入参数,不返回结果。

在我们的例子中,我们将把Map.Entry传递给Consumer,并与List项的键或值匹配。如果Entry符合条件,我们将把entry.getValue()添加到一个新的List中。

List<User> usersList = new ArrayList<>();
    
usersMap.entrySet().forEach( entry -> {
  if(idList.contains(entry.getValue().getId())) {
    usersList.add(entry.getValue());
  }
});

System.out.println(usersList);

程序输出。

[User(id=1, name=Alex), User(id=3, name=Brian), User(id=5, name=Charles), User(id=7, name=Don)]

5.结语

在这个Java教程中,我们学会了通过键或值过滤HashMap,并将匹配的Entry实例收集到子图中。我们还学会了在使用Stream.filter()forEach()API对Map的键进行过滤后,在List中收集值。