7

I have a map of the following type:

private HashMap<Integer, HashMap<String, Object>> entireMap;

The keys go from 1 - n. The subMap inside the entireMap is of the following type:

HashMap<String, Object> subMap = new HashMap<String, Object>();

Every key of the entire map contains this subMap (and a lot more):

subMap.put("user_name", usid[1]);

So i have something like this at the end:

{1 {"user_name" = "Arthur", "otherKeys = ..."}}
{2 {"user_name" = "Bela", "otherKeys = ..."}}
{3 {"user_name" = "Ceasar", "otherKeys = ..."}}
{4 {"user_name" = "Ceasar", "otherKeys = ..."}}
{5 {"user_name" = "Bela", "otherKeys = ..."}}
{6 {"user_name" = "Bela", "otherKeys = ..."}}

Now I want to count the max occurence of a user_name in the entireMap, in this case it would be 3 (bela occures three times).

How can I do that?

Cœur
  • 37,241
  • 25
  • 195
  • 267
sHarivaRi
  • 83
  • 1
  • 1
  • 9

4 Answers4

6

Here is an example of an implementation.

Note: don't use such map initialization in production code!

    HashMap<Integer, HashMap<String, Object>> entireMap = new HashMap<>();
    entireMap.put(1, new HashMap<String, Object>() {{
        put("user_name", "Arthur");
        put("other_key1", "val");
        put("other_key2", "val");
    }});
    entireMap.put(2, new HashMap<String, Object>() {{
        put("user_name", "Bela");
        put("other_key2", "val");
    }});
    entireMap.put(3, new HashMap<String, Object>() {{
        put("user_name", "Ceasar");
    }});
    entireMap.put(4, new HashMap<String, Object>() {{
        put("user_name", "Ceasar");
    }});
    entireMap.put(5, new HashMap<String, Object>() {{
        put("user_name", "Bela");
    }});
    entireMap.put(6, new HashMap<String, Object>() {{
        put("user_name", "Bela");
    }});

    Map<Object, Long> result = entireMap
            .values()
            .stream()
            .map(map -> map.get("user_name"))
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

    System.out.println(result);

    Long max = Collections.max(result.values());
    System.out.println(max);

Output:

{Ceasar=2, Arthur=1, Bela=3}
3
solomkinmv
  • 1,804
  • 3
  • 19
  • 30
  • 3
    Or without the `map()` call: `Map counts = entireMap.values() .stream() .collect(Collectors.groupingBy(v -> v.get("user_name"), Collectors.counting()));` – Eran Jun 12 '17 at 13:32
  • 1
    @Eran yes, of course. But I prefer to separate responsibilities for each operation – solomkinmv Jun 12 '17 at 13:35
1

If you don't want to go for java 8 feature than you can do it by simple iterating through the map.

Map<String, Integer> resultMap = new HashMap<String, Integer>();

for (int key : entireMap.keySet()) {
    String userName = (String) entireMap.get(key).get("user_name");

    if (resultMap.containsKey(userName)) {
        resultMap.put(userName, resultMap.get(userName) + 1);
    } else {
        resultMap.put(userName, 1);
    }
}

System.out.println(resultMap);

Output :

{Arthur=1, Ceasar=2, Bela=3}

Mit Mehta
  • 212
  • 1
  • 8
  • 2
    `resultMap.get(userName) + 1` will throw a NullPointerException. You probably would want to do `resultMap.getOrDefault(userName, 0)`. Or, prior to Java 8, something like `Integer count = resultMap.get(userName); resultMap.put(count != null ? count.intValue() + 1 : 1);`. – VGR Jun 12 '17 at 13:47
  • 1
    @VGR Doesn't his `resultMap.containsKey(userName)` condition prevent that from happening? – phatfingers Jun 12 '17 at 14:49
  • @phatfingers Yes, it does. I don’t know why I didn’t see that. – VGR Jun 12 '17 at 14:52
  • @VGR : If you have down voted me and if you think my answer is correct, than can you please revert your vote? It will help me to build my reputation. – Mit Mehta Jun 13 '17 at 05:18
  • The system will not permit me to change my vote unless you edit your question in some way. I suggest changing the first line to `Map resultMap`, as variable types should reference a contract (Map) rather than an implementation (HashMap). – VGR Jun 13 '17 at 10:14
0

Here's one way to do it using Java 8 features, but without streams:

Map<String, Long> counts = new HashMap<>();
entireMap.forEach((k, v) ->
    counts.merge(v.get("user_name"), 1L, Long::sum));

In the counts map you'll have the count for each user. Then you can find the entry with the max value:

Entry<String, Long> max = Collections.max(
    counts.entrySet(),
    Map.Entry.comparingByValue());
fps
  • 33,623
  • 8
  • 55
  • 110
0

In Java 7 or lower you can use Guava MultiSet:

List<Object> names = new ArrayList<>();
for (HashMap<String, Object> outerMap : entireMap.values()) {
    names.add(outerMap.get("user_name"));
}

HashMultiset<Object> objects = HashMultiset.create(names);

objects.forEachEntry((name, count) -> System.out.println(name + " -> " + count));

As a result:

Ceasar -> 2
Arthur -> 1
Bela -> 3
Danylo Zatorsky
  • 5,856
  • 2
  • 25
  • 49