【问题标题】:Java: How to use a pair of keys for HashMapJava:如何为 HashMap 使用一对键
【发布时间】:2011-08-11 21:17:17
【问题描述】:

从 sql 数据库中,我正在读取一个包含 2 个字段的表:appName、user。所以我可能会看到:

+-------------+
| appA | John |
+-------------+
| appB | Mary |
+-------------+
| appC | Tom  |
+-------------+
| appA | John |
+-------------+
| appA | Mary |
+-------------+

这些记录中的每一个都存储为具有 appName 和用户的 AppClass 的对象。 现在,我想列出不同用户运行应用程序的次数。所以:

+-----------------+
| appA | John | 2 |
+-----------------+
| appA | Mary | 1 | 
+-----------------+
| appB | Mary | 1 |  
+-----------------+
| appC | Tom  | 1 | 
+-----------------+

是否可以使用带有 2 个键的 HashMap 进行计数?

【问题讨论】:

  • 为什么不在SQL中进行分组和求和

标签: java sql map hashmap


【解决方案1】:

是的,可以创建一个包含 appName 和用户的 AppUser 类。为您的 AppUser 类覆盖 hashCode()equals()

然后您可以使用:

Map<AppUser, Integer> map;

【讨论】:

    【解决方案2】:

    是的。创建一个正确实现hashCode()equals() 的对,并将其用作键类型。如果您使用的是 apache commons 之类的库,您可能可以在那里找到一个 pair 或 tuple 类,否则下面的将起作用。

    不过,不要过度使用泛型对。定义一个键类来处理集合中一对项目之间的关系很好,但是很多人原则上反对在 Java 中广泛使用对类。

    public final class PairKey<A, B> {
      public final A a;
      public final B b;
    
      private PairKey(A a, B b) { this.a = a; this.b = b; }
    
      public static <A, B> PairKey<A, B> make(A a, B b) { return new PairKey<A, B>(a, b); }
    
      public int hashCode() {
        return (a != null ? a.hashCode() : 0) + 31 * (b != null ? b.hashCode() : 0);
      }
    
      public boolean equals(Object o) {
        if (o == null || o.getClass() != this.getClass()) { return false; }
        PairKey that = (PairKey) o;
        return (a == null ? that.a == null : a.equals(that.a))
            && (b == null ? that.b == null : b.equals(that.b));
      }
    }
    

    然后将 a 和 b 的条目放入地图中,只需这样做

    myMap.put(new PairKey(a, b), value)
    

    【讨论】:

      【解决方案3】:

      怎么样

      Map<String, Integer> appUserToCountMap
      

      例如使用appA:John 作为键

      【讨论】:

      • 这是一个非常危险的模式,除了最有限的情况。
      • 每个人都很高兴,直到出现名为“app1:v2.1”的应用程序。
      【解决方案4】:

      是的,你可以有如下结构:

      Map<String, Map<String, Integer>>
             ^           ^       ^
             appName    user    count
      

      但如果你直接从数据库中获取聚合数据会容易得多:

      SELECT appName, user, COUNT(*)
      FROM table
      GROUP BY appName, user;
      

      【讨论】:

        【解决方案5】:

        您也可以考虑使用 Commons Collections 的包。见Bag.getCount(key)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-12-31
          • 2017-06-30
          • 2017-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多