Я только начал смотреть на Java 8 и попробовать лямбды, я подумал, что попробую переписать очень простую вещь, которую написал недавно. Мне нужно превратить карту строки в столбец в другую карту строки в столбец, где столбец на новой карте является защитной копией столбца на первой карте. Столбец имеет конструктор копирования. Ближайшее, что у меня есть, это:
Map<String, Column> newColumnMap= new HashMap<>();
originalColumnMap.entrySet().stream().forEach(x -> newColumnMap.put(x.getKey(), new Column(x.getValue())));
но я уверен, что должен быть лучший способ сделать это, и я был бы признателен за совет.
Map<String, Integer> map = new HashMap<>(); map.put("test1", 1); map.put("test2", 2); Map<String, Integer> map2 = new HashMap<>(); map.forEach(map2::put); System.out.println("map: " + map); System.out.println("map2: " + map2); // Output: // map: {test2=2, test1=1} // map2: {test2=2, test1=1}
Вы можете использовать этот
forEach
метод, чтобы делать то, что хотите.Что вы там делаете:
map.forEach(new BiConsumer<String, Integer>() { @Override public void accept(String s, Integer integer) { map2.put(s, integer); } });
Что мы можем упростить до лямбда:
И поскольку мы просто вызываем существующий метод, мы можем использовать ссылку на метод , которая дает нам:
источник
originalColumnMap.forEach((string, column) -> newColumnMap.put(string, new Column(column)));
или я могу ее сократить?new Column(column)
в качестве параметра, вам придется пойти с этим.Способ без повторной вставки всех записей в новую карту должен быть самым быстрым, потому чтоHashMap.clone
внутренне выполняетповторноехеширование.Map<String, Column> newColumnMap = originalColumnMap.clone(); newColumnMap.replaceAll((s, c) -> new Column(c));
источник
Map<String,Column> newColumnMap = new HashMap<>(originalColumnMap);
. Не знаю, под одеялом ли что-то по-другому.Map
поведение реализации, т. Е. ЕслиMap
естьEnumMap
илиSortedMap
, результатMap
также будет. В случаеSortedMap
со специальным значениемComparator
это может иметь огромное смысловое различие. Ну что ж, то же самое относится кIdentityHashMap
…Сохраняйте простоту и используйте Java 8: -
источник
Если вы используете в своем проекте Guava (минимум v11), вы можете использовать Maps :: transformValues .
Map<String, Column> newColumnMap = Maps.transformValues( originalColumnMap, Column::new // equivalent to: x -> new Column(x) )
Примечание: значения этой карты оцениваются лениво. Если преобразование обходится дорого, вы можете скопировать результат на новую карту, как это предлагается в документации Guava.
To avoid lazy evaluation when the returned map doesn't need to be a view, copy the returned map into a new map of your choosing.
источник
To avoid lazy evaluation when the returned map doesn't need to be a view, copy the returned map into a new map of your choosing.
Вот еще один способ, который дает вам доступ к ключу и значению одновременно, если вам нужно выполнить какое-то преобразование.
Map<String, Integer> pointsByName = new HashMap<>(); Map<String, Integer> maxPointsByName = new HashMap<>(); Map<String, Double> gradesByName = pointsByName.entrySet().stream() .map(entry -> new AbstractMap.SimpleImmutableEntry<>( entry.getKey(), ((double) entry.getValue() / maxPointsByName.get(entry.getKey())) * 100d)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
источник
Если вы не против использования сторонних библиотек, моя cyclops-react lib имеет расширения для всех типов JDK Collection , включая Map . Вы можете напрямую использовать методы map или bimap для преобразования вашей карты. MapX может быть построен из существующей карты, например.
MapX<String, Column> y = MapX.fromMap(orgColumnMap) .map(c->new Column(c.getValue());
Если вы также хотите изменить ключ, вы можете написать
MapX<String, Column> y = MapX.fromMap(orgColumnMap) .bimap(this::newKey,c->new Column(c.getValue());
bimap можно использовать для одновременного преобразования ключей и значений.
Поскольку MapX расширяет Map, сгенерированная карта также может быть определена как
источник