Java - возможно ли добавить ключ / значение на карту внутри карты в 1 строке кода? - PullRequest
3 голосов
/ 01 сентября 2009

У меня есть HashMap 1, который содержит 5 ключей, все из которых имеют Hashmaps в качестве значений. Я хочу добавить пары ключ / значение в эти подкарты.

map1.get(subCategoryMap).put(newKey, newValue); 

Я думаю:

map1.get(subCategoryMap);

возвращает другую карту. Я мог бы разбить эту строку на две строки и иметь:

map2 = map1.get(subCategoryMap);
map2.put(newKey, newValue);

Но я бы предпочел сделать это за один шаг. Вот почему я пытаюсь

map1.get(subCategoryMap).put(newKey, newValue); 

Это не работает (не нравится .put () для объекта). Можно ли получить доступ к вложенной карте и добавить к ней ту же строку кода, как я выше, или мне нужно разбить ее на 2 строки?

Ответы [ 8 ]

14 голосов
/ 01 сентября 2009

С помощью дженериков вы можете:

Map<String, Map<String, String>> map1 = ...
map1.get(category).put(subcategory, value);

Если карты не являются общими:

Map map1 = ...
((Map)map1.get(category)).put(subcategory, value);
9 голосов
/ 01 сентября 2009
((Map)map1.get(subCategoryMap)).put(newKey, newValue);

Или используйте дженерики:

Map<X, Map<Y,Z>> map1;

...

map1.get(subCategoryMap).put(newKey, newValue);

Однако оба метода завершатся неудачно с NullPointerException, если map1 не содержит сопоставления для subCategoryMap.

3 голосов
/ 01 сентября 2009

Просто в стороне (я бы сделал это комментарий, но я думаю, что это будет немного долго) ...

Программисту очень приятно иметь возможность получить одну концептуальную операцию в одной строке. Программисту (в то время) он кажется более читаемым, логичным и просто правильным.

Это почти никогда не бывает хорошо. С одной стороны, позже будет сложнее разобрать, чем две строки - даже если ваша внутренняя реакция сейчас такова, что она более читабельна. Также - чем больше операций в одной строке, тем сложнее отлаживать.

Для удобства чтения я бы сказал, что решение Generics - это примерно столько же, сколько я бы поставил в одну строку - для решения для литья я бы разбил его на две строки; Я также разбил бы его на несколько строк, если бы один из параметров был операцией, а не просто переменной.

Я знаю, что многие люди не согласятся с этим и, скажу вам правду, сначала я склоняюсь к одной строке, но я заметил, что при первых признаках неприятностей или каких-либо путаница облегчает мою жизнь, разбивая все на отдельные утверждения с четко названными переменными.

По крайней мере, так же важно - в случаях с вложенными коллекциями я часто также оборачиваю коллекции в другой объект. Это было бы интересно в вашем случае - вызов станет немного более понятным.

dataHolder.put(category, newKey, newVale);

Скрывает механизм вложения коллекций (который в противном случае может быть сложным для запоминания правильно и легко испортить) и делает ваши намерения намного более ясными.

Этот шаблон оборачивания (не расширяющий, но инкапсулирующий) вложенных коллекций поначалу кажется странным, но я действительно советую вам просто попробовать - он действительно очищает много кода, делает все намного безопаснее, добавляет понимание каждому, изменения «Коллекция» в бизнес-объекте (где вы можете разместить бизнес-методы - рефакторинг вы оцените почти сразу), и он просто помогает всему вашему коду.

0 голосов
/ 01 сентября 2009

Работает нормально, если вы используете дженерики:

Map<String,Map<String,Integer>> map = new HashMap<String,Map<String,Integer>>();
map.put("Test", new HashMap<String,Integer>());
map.get("Test").put("Some", 1);
0 голосов
/ 01 сентября 2009

Вы можете использовать ((HashMap)map1.get(subCategoryMap)).put(newKey, newValue);

Кроме того, если вы используете Java 5 или Java 6, вы можете использовать generic, чтобы избежать приведения в HashMap

0 голосов
/ 01 сентября 2009

Пока map1 объявлено что-то вроде Map<OuterKey, Map<InnerKey, MyValue>>, будет работать одна строка. Однако вы должны быть осторожны с тем, что произойдет, если subCategoryMap не существует в map1 & mdash; однострочник вызовет NullPointerException.

0 голосов
/ 01 сентября 2009

Если вы используете общие коллекции, то ваш код должен работать как написано. В противном случае вам необходимо добавить соответствующие приведения в одну строку.

0 голосов
/ 01 сентября 2009

Если вы не используете Generics, то HashMap сохраняет и извлекает ключи и значения в виде Object, поэтому вам может потребоваться приведение, которое будет выглядеть примерно так:

((HashMap)map1.get(subCategoryMap)).put(newKey, newValue);

Однако было бы полезно, если бы вы предоставили больше кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...