Java: как использовать пару ключей для HashMap

Из базы данных sql я читаю таблицу с 2 полями: appName, user. Так что я могу видеть:

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

Каждая из этих записей хранится в виде объекта AppClass с appName и user. Теперь я хочу перечислить, сколько раз приложения запускались разными пользователями. Так:

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

Можно ли сделать подсчет с помощью HashMap с 2 ключами?

5 ответов

Решение

Да, у вас может быть такая структура:

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

Но было бы намного проще, если бы вы просто извлекали агрегированные данные непосредственно из базы данных:

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

Да, это возможно, создать AppUser класс, который включает appName и пользователя. Override hashCode() а также equals() для тебя AppUser учебный класс.

Затем вы можете использовать:

Map<AppUser, Integer> map;

Да. Создайте пару, которая реализует hashCode() а также equals() правильно и используйте это как тип ключа. Если вы используете библиотеку, такую ​​как Apache Commons, вы, вероятно, можете найти там класс пары или кортежа, но в противном случае будет работать нижеследующее.

Не переусердствуйте с общими парами. Можно определить ключевой класс для обработки отношений между парой элементов в коллекции, но у многих есть принципиальные возражения против широкого использования парных классов в 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)

Как насчет

Map<String, Integer> appUserToCountMap

использование appA:John в качестве ключа, например,

Вы также можете рассмотреть возможность использования сумки Commons Collections'. Увидеть Bag.getCount(key)

Другие вопросы по тегам