0

From a sql database, I am reading a table with 2 fields: appName, user. So I may see:

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

Each of these records is stored as an object of a AppClass with appName and user. Now, i want to list how many times the apps were run by different users. So :

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

Is it possible do the counting with a HashMap with 2 keys?

João Silva
  • 89,303
  • 29
  • 152
  • 158
Ag Dsa
  • 5
  • 1
  • 1
  • 2

5 Answers5

5

Yes it is possible, create an AppUser class that includes the appName and the user. Override hashCode() and equals() for your AppUser class.

You can then use a:

Map<AppUser, Integer> map;
Marcelo
  • 11,218
  • 1
  • 37
  • 51
5

Yes. Create a pair that implements hashCode() and equals() properly and use that as the key type. If you're using a library like apache commons you can probably find a pair or tuple class there, but otherwise the below will work.

Don't overdo generic pairs though. It's fine to define a key class to handle the relationship between a pair of items in a collection, but many people have principled objections to wide use of pair classes in 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));
  }
}

and then to put an entry for a and b into the map, just do

myMap.put(new PairKey(a, b), value)
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
3

how about

Map<String, Integer> appUserToCountMap

use appA:John as key for example

jmj
  • 237,923
  • 42
  • 401
  • 438
2

Yes, you can have a structure like the following:

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

But it'd be much easier if you just fetch the aggregated data directly from the database:

SELECT appName, user, COUNT(*)
FROM table
GROUP BY appName, user;
João Silva
  • 89,303
  • 29
  • 152
  • 158
0

You can also consider using Commons Collections' Bag. See Bag.getCount(key)

Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52