收集 Map.Entry 第一个值到地图中

Meh*_*lik 2 java collections hashmap java-8 java-stream

我有以下地图:

private static Map<String, String[]> createMap(){
    Map<String, String[]> map = new HashMap<>();
    map.put("A", new String[]{null});
    map.put("B", new String[]{"Banana"});
    map.put("C", new String[]{""});
    map.put("D", new String[]{"Duck"});
    return map;
}
Run Code Online (Sandbox Code Playgroud)

我想把这张地图转换成Map<String, String>

所需输出:

关键 :B 价值 : 香蕉

关键 :D 值 : 鸭子

我想使用Java 8 Stream APIsand 来执行此操作,并且我尝试过的解决方案之一是

final Map<String, String[]> collect = createMap().entrySet().stream()
        .filter(e -> e.getValue()[0] != null && !"".equals(e.getValue()[0]))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

collect.forEach((key, value) -> System.out.println("Key :" + key + " Value :" + Arrays.toString(value)));
Run Code Online (Sandbox Code Playgroud)

但这给了我Map<String, String[]>,输出是

键:B 值:[香蕉]

键:D 值:[鸭]

如何告诉 Collector 仅从Map.Entry值中提取第一个值?

Had*_*i J 5

你可以做:

map.entrySet().stream()
          .filter(entry -> Stream.of(entry.getValue()[0])
                                .anyMatch(s -> s != null && !s.isEmpty()))
          .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue()[0]))
Run Code Online (Sandbox Code Playgroud)

通过你的代码:

Map<String, String> collect = map.entrySet().stream()
            .filter(e -> e.getValue()[0] != null && !e.getValue()[0].isEmpty())
            .collect(Collectors.toMap(Map.Entry::getKey, entry->entry.getValue()[0]));
Run Code Online (Sandbox Code Playgroud)

  • 我没有看到将第一个数组元素的测试转变为“allMatch”的优点,当有一些元素时,“allMatch”会测试其他不相关的元素。但是将 `"".equals(e.getValue()[0])` 转换为 `e.getValue()[0].isEmpty()` 是一个好主意。 (4认同)