Создание сложного HashMap в Java

Самый простой способ создать HashMap следующим образом:

( student1 => Map( name => Tim, Scores => Map( math => 10, physics => 20, Computers => 30), place => Miami, ranking => Array(2,8,1,13), ), student2 => Map ( ............... ............... ), ............................ ............................ ); 

Я попробовал это:

 HashMap record = new HashMap(); record.put("student1", new HashMap()); record.get("student1").put("name","Tim"); record.get("student1").put("Scores", new HashMap()); 

Но я получаю ошибку. Я делаю так, потому что record.get("student1") является объектом HashMap, поэтому я предполагаю, что на нем должно работать, и так далее.

Если он не работает, что это лучший способ сделать это?

Вы получаете это исключение, потому что get() возвращает объект типа. вам нужно отбросить это на Map .

 ((Map)record.get("student1")).put("name","Tim"); 

Вы можете сделать это по типу, отбрасывая Object to Map или HashMap .

 HashMap record = new HashMap(); record.put("student1", new HashMap()); ((HashMap)record.get("student1")).put("name","Tim"); ((HashMap)record.get("student1")).put("Scores", new HashMap()); 

Тем не менее, как я уже говорил, вы уверены, что хотите этот дизайн?

Java – это статически и номинально типизированный язык. Таким образом, стиль кодирования, который вы следуете, не является предпочтительным. Вместо этого вы должны создавать classы и объекты.

Тем не менее, Guava предоставляет несколько classов утилиты, таких как Lists , Iterables , Maps т. Д., Которые позволяют создавать соответствующие объекты коллекции из varargs.

Хотя я согласен с другими комментаторами в том, что предпочитаю создавать подходящие classы для ваших объектов домена, мы можем упростить синтаксис построения карты с помощью некоторых вспомогательных методов:

 Map map = map( entry("student1", map( entry("name", "Tim"), entry("scores", map( entry("math", 10), entry("physics", 20), entry("Computers", 30) )), entry("place", "Miami"), entry("ranking", array(2, 8, 1, 13)) )), entry("student2", map( // ... )) ); // map.toString(): // {student2={}, student1={scores={math=10, physics=20, Computers=30}, name=Tim, place=Miami, ranking=[2, 8, 1, 13]}} 

Вам просто нужно определить вспомогательный class, как показано ниже, и использовать статический импорт:

 import static com.example.MapHelper.*; 

Класс помощника:

 package com.example; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MapHelper { public static class Entry { private String key; private Object value; public Entry(String key, Object value) { this.key = key; this.value = value; } public String getKey() { return key; } public Object getValue() { return value; } } public static Map map(Entry... entries) { Map map = new HashMap(); for (Entry e : entries) { map.put(e.getKey(), e.getValue()); } return map; } public static Entry entry(String k, Object v) { return new Entry(k, v); } public static List array(Object... items) { List list = new ArrayList(items.length); for (int i = 0; i < items.length; i++) { list.add(i, items[i]); } return list; } } 

Ну, «Java» способ сделать это – разбить эти объекты на classы. В примере, который вы указали, похоже, что вы можете создать class Student который содержит такие атрибуты, как имя, место, местоположение и т. Д.

Это намного чище, чем заставлять все на такой карте.

Почему вы создаете сложный набор HashMaps, вы можете вместо этого создать объект Java, а затем использовать его для HashMap.

Таким образом, в вашем случае вы можете создать class ScoreInfo, который будет иметь оценку, место и ранжирование HashMap, а затем использовать это как значение HashMap .

замещать

 HashMap record = new HashMap(); 

с

 Map> record = new HashMap>(); 

Но, это не имеет смысла ставить разные типы объектов в качестве значений. Если следующая строка по ошибке,

 record.get("student1").put("Scores", new HashMap()); 

то вы также можете упростить определение.

 Map record = new HashMap(); 

Успение: вы используете JDK 1.5+