Java:创建 HashMaps ArrayList 的副本,但仅包含某些键

Eli*_*ott 1 java arraylist java-stream

考虑以下数据结构:

ArrayList<HashMap<String, String>> entries = new ArrayList<>();

ArrayList<String> keyNamesToInclude = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

此代码创建条目的副本但哈希映射仅包含 keyNamesToInclude 中的键:

ArrayList<HashMap<String, String>> copies = new ArrayList<>();

for (HashMap<String, String> entry: entries) {
  HashMap<String, String> copy = new HashMap<>();
  for (String keyName: keyNamesToInclude) {
    copy.put(keyName, entry.get(keyName));
  }
  copies.add(copy);
}
Run Code Online (Sandbox Code Playgroud)

如何以一种功能性的方式使用 Streams 来创建它?

Ale*_*nko 5

最好转换keyNamesToIncludeSet,以便于查找键。

然后用于List::stream获取Stream<HashMap>和为每个地图获取其条目的过滤流,重新收集到新地图中并相应地列出。

Set<String> keys = new HashSet<>(keyNamesToInclude); // removes possible duplicates
List<Map<String, String>> copies = entries.stream() // Stream<HashMap>
    .map(m -> m.entrySet()
        .stream()
        .filter(e -> keys.contains(e.getKey()))
        .collect(Collectors.toMap(
            Map.Entry::getKey, Map.Entry::getValue
        ))
    )
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

如果具有and in 的具体实现非常重要,则可能需要强制转换或特殊形式的收集器,即使返回和返回:ListMapcopiesCollectors.toList()ArrayListCollectors.toMapHashMap

// casting
ArrayList<HashMap<String, String>> copies2 = (ArrayList) entries.stream() // Stream<HashMap>
    .map(m -> (HashMap<String, String>) m.entrySet()
        .stream()
        .filter(e -> keys.contains(e.getKey()))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
    )
    .collect(Collectors.toList());

// special collectors
// toMap(keyMapper, valueMapper, mergeFunction, mapFactory)
// toList -> toCollection(ArrayList::new)
ArrayList<HashMap<String, String>> copies3 = entries.stream() // Stream<HashMap>
    .map(m -> m.entrySet()
        .stream()
        .filter(e -> keys.contains(e.getKey()))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, HashMap::new))
    )
    .collect(Collectors.toCollection(ArrayList::new));
Run Code Online (Sandbox Code Playgroud)