【问题标题】:put and get for nested hashmap in java在java中放置和获取嵌套的哈希图
【发布时间】:2018-02-24 08:57:02
【问题描述】:

我真的是 Java 新手,我正在尝试使用 Hashmap 来实现一些东西。

以下代码是我首先声明的:

private HashMap<String, TreeMap<Object, Object>> submissions = new HashMap<String, TreeMap<Object, Object>>();;

还有,

public Submission add(String unikey, Date timestamp, Integer grade) {

        // check the argument
        if(unikey == null || timestamp == null || grade == null) {
            throw new IllegalArgumentException("Null argument detected\n");
        }
}

这就是我现在正在写的。假设有名为“人”、“数据”和“等级”的项目。有人可以告诉我如何将它们放入嵌套的哈希图中吗?我为另一个名为 MySubmissions 的类中的每个项目编写了 getter 和 setter。

提交是用另一个类编写的接口,包含以下方法:

public String getPerson();
public Date getTime();
public Integer getGrade();

我想要实现的是,例如,

?.add("aaaa1234", df.parse("2016/09/03 09:00:00"), 10);
?.add("aaaa1234", df.parse("2016/09/03 16:00:00"), 20);
?.add("cccc1234", df.parse("2016/09/03 16:00:00"), 30);
?.add("aaaa1234", df.parse("2016/09/03 18:00:00"), 40);

谢谢!

(我真正想要实现的是,我想将数据添加到哈希图中。然后使用另一种称为 getBestGrade 的方法,我想获得列表中评分最高的人,但我只想知道如何存储首先使用 put 和 get 进入 hashmap...)

【问题讨论】:

  • 为什么需要这个嵌套的地图地图?
  • 什么是Submission?您到底想实现什么(输入-> 输出)。你使用什么结构,为什么?请完成您的问题。
  • 不确定您的意思,但submissions.get("aaaa1234").put(df.parse("2016/09/03 09:00:00"), 10); 可能是一个起点。
  • 因为有人告诉我添加或删除比 O(n) 花费时间...
  • @승기유 - 如果您展示具有 O(n) 性能的代码并要求基于 Map 的替代方案,这可能会有所帮助。然后我们知道预期的行为。 (或者更好的是,向我们展示输入和预期输出)

标签: java data-structures hashmap


【解决方案1】:

我只是要描述如何使用地图的地图 - 由您决定这是否是您真正想要使用的。我将使用名为ABC 等的类——你可以替换自己的类,包括StringSubmission,如果你愿意的话。

在解决这个问题之前,请确保您对单级 Map 有一个深刻的理解——equals()hashCode() 对于 HashMap 等来说是必需的。

您可以像以前那样定义地图地图:

Map<A, ? extends Map<B,C>> mapOfMaps;

一般来说,给变量一个类型为Map 而不是HashMapTreeMap——你通常不需要实现类的任何更具体的方法。如果你愿意,你总是可以改变的。 ? extends Map&lt;&gt; 部分允许您的 map-of-maps 包含 Map 的任意实现。

你可以这样实例化它:

Map<A, ? extends Map<B,C>> mapOfMaps = new HashMap<>();
// or with explicit (unnecessary) type declarations:
Map<A, ? extends Map<B,C>> mapOfMaps = new HashMap<A, ? extends Map<B,C>>();

现在你有一个空的地图。您可以为其添加地图:

Map<B,C> map = new HashMap<>();
mapOfMaps.put(new A(1), map);

现在您有一个包含一张空地图的地图地图。或者您可以添加包含某些内容的地图:

Map<B,C> map = new HashMap<>();
map.put(b, c);
mapOfMaps.put(a, map);

很可能,当您不知道它是否存在时,您想将项目添加到 Map&lt;B,C&gt;。这里没有捷径 - 你必须这样做:

void addToMapOfMaps(A a, B b, C c) {
   Map<B,C> map = mapOfMaps.get(a);
   if(map == null) {
      map = new HashMap<>();
      mapOfMaps.put(a,map);
   }
   map.put(b,c);
}

请注意,如果多个线程同时执行此操作,则会出现问题。

同样,如果您只是阅读,则必须在两个级别处理缺失的元素:

C get(A a, B b) {
    Map<B,C> map = mapOfMaps.get(a);
    if(map == null) {
         return null;
    }
    return map.get(b);
}

(或更简洁)

C get(A a, B b) {
    Map<B,C> map = mapOfMaps.get(a);
    return map == null ? null : map.get(b);
}

【讨论】:

    【解决方案2】:

    我想他想知道如何为每个人存储多个提交。你可以这样做:

    import java.util.Date;
    import java.util.HashMap;
    import java.util.TreeMap;
    
    public final class BestGrade
    {
        private static final HashMap<String, TreeMap<Date, Integer>> SUBMISSIONS = new HashMap<String, TreeMap<Date, Integer>>();
    
        private BestGrade()
        {}
    
        public static void main(final String[] args)
        {
            // How to add
            add("Person1", new Date(), Integer.valueOf(1));
            add("Person1", new Date(), Integer.valueOf(10));
            add("Person1", new Date(), Integer.valueOf(20));
            add("Person2", new Date(), Integer.valueOf(1));
            add("Person3", new Date(), Integer.valueOf(30));
            add("Person3", new Date(), Integer.valueOf(40));
    
            // How to get best grade
            final Integer bestGradePerson1 = getBestGrade("Person1");
            final Integer bestGradePerson3 = getBestGrade("Person2");
            final Integer bestGradePerson2 = getBestGrade("Person3");
    
            System.out.println("Bestgrade Person1: " + bestGradePerson1);
            System.out.println("Bestgrade Person2: " + bestGradePerson2);
            System.out.println("Bestgrade Person3: " + bestGradePerson3);
        }
    
        public static void add(final String key, final Date timestamp, final Integer grade)
        {
            // TODO the same for timestamp and grade
            if (key == null || key.trim().isEmpty()) {
                throw new IllegalArgumentException("key must not be null");
            }
    
            // Get
            TreeMap<Date, Integer> submission = SUBMISSIONS.get(key);
            // Create your treemap if not already exists, before adding new value to avoid NullPointerException
            if (submission == null) {
                submission = new TreeMap<Date, Integer>();
                SUBMISSIONS.put(key, submission);
            }
            submission.put(timestamp, grade);
        }
    
        public static Integer getBestGrade(final String key)
        {
            Integer bestGrade = null;
    
            final TreeMap<Date, Integer> submission = SUBMISSIONS.get(key);
            if (submission == null) {
                // When no submission available, return null or any other value you wish to show there is no best grade
                return bestGrade;
            }
    
            for (final Integer grade : submission.values()) {
                if (bestGrade == null) {
                    bestGrade = grade;
                }
                // Set new grade when values is higher than before
                else if (bestGrade.intValue() < grade.intValue()) {
                    bestGrade = grade;
                }
            }
            return bestGrade;
        }
    }
    

    【讨论】:

      【解决方案3】:

      创建实体

      public class Submission {
      
          private Date timestamp;
      
          private Integer grade;
      
      
          public Date getTimestamp() {
              return timestamp;
          }
      
          public void setTimestamp(Date timestamp) {
              this.timestamp = timestamp;
          }
      
          public Integer getGrade() {
              return grade;
          }
      
          public void setGrade(Integer grade) {
              this.grade = grade;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
      
              Submission that = (Submission) o;
      
              if (timestamp != null ? !timestamp.equals(that.timestamp) : that.timestamp != null) return false;
              return grade != null ? grade.equals(that.grade) : that.grade == null;
          }
      
          @Override
          public int hashCode() {
              int result = timestamp != null ? timestamp.hashCode() : 0;
              result = 31 * result + (grade != null ? grade.hashCode() : 0);
              return result;
          }
      }
      

      创建一个 HashMap

      private HashMap<String, Submission> map = new HasMap<>();
      

      添加

      map.add("key", new Submission());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-21
        • 2015-04-16
        • 1970-01-01
        • 1970-01-01
        • 2020-11-21
        • 1970-01-01
        相关资源
        最近更新 更多