У меня есть список HashMap<Integer, ArrayList<String>>
, и я хотел бы объединить их в цикле.
Проблема в том, что ключ каждой карты начинается с 0, поэтому ключи будут дублироваться. putAll()
не работает, так как он переопределяет клавиши и всегда дает мне последнюю карту.
Я видел примеры объединения двух карт с помощью Stream, но в моем случае может быть больше двух карт. Я пытаюсь создать объединенную карту с инкрементным ключом. Например:
Допустим, у меня в списке 2 карты (может быть больше), и оба ключа начинаются с 0, но заканчиваются на разные значения.
1-я карта, ключ начинается с 0 и заканчивается на 10
2 карта, ключ начинается с 0 заканчивается на 15
Можно ли добавить вторую карту с ключом начиная с 11? В конце концов, мне нужна объединенная карта, в которой первый ключ начинается с 0, а последний ключ заканчивается на 25.
Я предполагаю, что вы имеете в виду объединение строковых списков записей карты с одним и тем же ключом?
@RajaShekar отредактировал вопрос, чтобы уточнить, что мне нужно. Ключи должны быть инкрементными.
Я бы перебирал любое количество карт, которые у вас есть, а затем для каждой карты, которую вы хотите объединить, перебирал записи. Для каждой записи вы можете использовать calculateIfAbsent , чтобы условно создать пустой список для ключа, а затем вызвать addAll для значения. Например.:
List<Map<Integer, List<String>>> maps = List.of(
Map.of(1, List.of("hello")),
Map.of(2, List.of("world")),
Map.of(1, List.of("a"), 2, List.of("b"))
);
Map<Integer, List<String>> combined = new HashMap<>();
for (Map<Integer, List<String>> map : maps) {
for (Map.Entry<Integer, List<String>> e : map.entrySet()) {
combined.computeIfAbsent(e.getKey(), k -> new ArrayList<>()).addAll(e.getValue());
}
}
Привет Мурейник, большое спасибо за ваш ответ. К сожалению, карты не объединены, и я все еще получаю последнюю карту.
@Cugomastik Тогда я предлагаю предоставить минимальный воспроизводимый пример в вопросе. Приведенный выше код определенно объединяет карты в одну (работает в JShell).
Если вы предпочитаете потоковый подход
Map<Integer, List<String>> m1;
Map<Integer, List<String>> m2;
Map<Integer, List<String>> m3;
Map<Integer, List<String>> combined = new HashMap<>();
Stream
.of(m1, m2, m3)
.flatMap(m -> m.entrySet().stream())
.forEach(e -> combined.computeIfAbsent(e.getKey(), k -> new ArrayList<>())
.addAll(e.getValue()));
Спасибо за ваш ответ, но что, если нужно объединить 50 карт? Можно ли его использовать в цикле?
В случае 50, я ожидаю, что у вас будет их список. Затем вы можете транслировать список. List<Map<Integer, List<String>>> maps
. Вы можете использовать maps.stream(), а затем остальную часть кода.
Большое спасибо за ваш ответ. Я адаптировал код и попробовал его со списком карт, но получил только последнюю карту.
В приведенном выше примере вы найдете все записи на объединенной карте.
Предполагая, что у вас есть список карт, где ключи каждой карты являются целыми числами в диапазоне [0-k], [0-n], [0, r] ...
, и ваша результирующая карта должна иметь ключ, установленный в диапазоне [0 - (k+n+r..)]
, должно работать что-то вроде следующего:
public static void main(String[] args) throws IOException {
//example list of maps
List<Map<Integer,List<String>>> mapList = List.of(
Map.of( 0,List.of("foo","foo"),
1,List.of("bar","bar"),
2,List.of("baz","baz")),
Map.of( 0,List.of("doo","doo"),
1,List.of("gee","gee"),
2,List.of("woo","woo")),
Map.of( 0,List.of("cab","cab"),
1,List.of("kii","kii"),
2,List.of("taa","taa"))
);
AtomicInteger ai = new AtomicInteger();
Map<Integer,List<String>> result =
mapList.stream()
.flatMap(map -> map.values().stream())
.collect(Collectors.toMap(list -> ai.getAndIncrement(), Function.identity()));
result.forEach((k,v) ->{
System.out.println(k + " : " + v);
});
}
@Cugomastik Добро пожаловать. Рад, что смог помочь
Я знаю, что вы просили карту, но на основе вашего объяснения вашего окончательного решения и того факта, что ваши ключи теперь представляют собой последовательные целые числа, начинающиеся с 0, вы могли бы создать просто List<List<String>>
. В этом случае вы можете сделать это следующим образом:
List<List<String>> result = mapList.stream()
.flatMap(map->map.values().stream())
.collect(Collectors.toList());
HashMap не допускает дублирования ключей, поэтому ключи будут переопределены. Чего именно вы пытаетесь достичь здесь в качестве вывода?