Сглаживание вложенного Hashmap с помощью Stream
У меня есть вложенный HashMap<String,Object>
и я хочу создать HashMap<String,String>
сглаживая Hashmap. Я пробовал решение из Рекурсивно сгладить значения вложенных карт в Java 8. Но я не могу использовать класс FlatMap
как уже упоминалось в ответе.
Я также попробовал решение в самом вопросе, все еще что-то упускаю. Затем я нашел похожий вариант использования и нашел следующее решение. Но похоже, что я что-то упускаю в качестве параметра для лямбда-функции flatMap
,
public static void main(String[] args) {
Map<String,Object> stringObjectMap= new HashMap<String,Object>();
stringObjectMap.put("key1","value1");
stringObjectMap.put("key2","value2");
Map<String,Object> innerStringObjectMap = new HashMap<>();
innerStringObjectMap.put("i1key3","value3");
innerStringObjectMap.put("i1key4","value4");
innerStringObjectMap.put("i1key5","value5");
stringObjectMap.put("map1",innerStringObjectMap);
Map<String,Object> innerStringObjectMap2 = new HashMap<>();
innerStringObjectMap.put("i2key6","value6");
innerStringObjectMap2.put("i2key7","value7");
innerStringObjectMap.put("i1map2",innerStringObjectMap2);
Map<String,Object> collect =
stringObjectMap.entrySet().stream()
.map(x -> x.getValue())
.flatMap(x -> x) //I aint sure what should be give here
.distinct(); //there was a collect as List which i removed.
//collect.forEach(x -> System.out.println(x));
}
Что является лучшим решением для выравнивания вложенной карты? Меня интересуют не только значения, но и ключи на карте. Вот почему я решил сгладить карту, чтобы получить другую карту (я не уверен, возможно ли это вообще)
РЕДАКТИРОВАТЬ - Ожидаемый результат
key1 - value1
key2-value2
map1 ="" //this is something i will get later for my purpose
i1key3=value3
.
.
i1map2=""
.
.
i2key7=value7
2 ответа
Я изменил класс из упомянутого ответа в соответствии с вашими потребностями:
public class FlatMap {
public static Stream<Map.Entry<?, ?>> flatten(Map.Entry<?, ?> e) {
if (e.getValue() instanceof Map<?, ?>) {
return Stream.concat(Stream.of(new AbstractMap.SimpleEntry<>(e.getKey(), "")),
((Map<?, ?>) e.getValue()).entrySet().stream().flatMap(FlatMap::flatten));
}
return Stream.of(e);
}
}
Использование:
Map<?, ?> collect = stringObjectMap.entrySet()
.stream()
.flatMap(FlatMap::flatten)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(u, v) -> throw new IllegalStateException(String.format("Duplicate key %s", u)),
LinkedHashMap::new));
Внимание:
Обязательно используйте предоставленный collect
с LinkedHashMap
В противном случае порядок будет облажаться.
Я использовал функцию из /questions/1828672/sglazhivanie-vlozhennogo-hashmap-s-pomoschyu-stream/1828685#1828685. Но я использовал эту функцию по-другому.
Map<Object, Object> collect = new HashMap<>();
stringObjectMap.entrySet()
.stream()
.flatMap(FlatMap::flatten).forEach(it -> {
collect.put(it.getKey(), it.getValue());
});
Функция снова
public static Stream<Map.Entry<?, ?>> flatten(Map.Entry<?, ?> e) {
if (e.getValue() instanceof Map<?, ?>) {
return Stream.concat(Stream.of(new AbstractMap.SimpleEntry<>(e.getKey(), "")),
((Map<?, ?>) e.getValue()).entrySet().stream().flatMap(FlatMap::flatten));
}
return Stream.of(e);
}