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)