truth_seeker
truth_seeker

Reputation: 363

Logic to count the number of entries corresponding to each value in a hashmap in java

Currently I have sorted my Hashmap on the values field. I need to count the number of entries associated with each value in the hashmap.

Initially i thought of iterating over the sorted hashmap and counting the number of entries till the value did not change. In order to get the next value, I need to get to the next entry, but there is no way to do that till one loop iteration ends. But I was just lost in the logic and could not proceed. :(

I tried the other logic which uses filters in stream(). Applying the filter on the values being 1 to 50 and then counting the entries which satisfy the predicate.

for(int i = 1; i < COUNT; i++){
            int count = (int) single_count.entrySet().stream().filter(v -> v.getValue() == 1).count(); //collect(Collectors.toList());
            unigram_Nc.put(i, count);
        }

In this case I was aware of the values in the hashmap. But I would like to know the generic solution which returns the number of entries in a hashmap corresponding to each value. Is there any other way to count the number of entries having a particular value without knowing the values before hand ?

Upvotes: 1

Views: 2020

Answers (3)

Dinesh Pun
Dinesh Pun

Reputation: 28

try this simple logic

Map<String,Integer> dataMap=new LinkedHashMap<String,Integer>(); //Your data map
    Map<Integer,Integer> countMap=new LinkedHashMap<Integer,Integer>(); //map to count data map entries

    //initializing with default value
    dataMap.put("a", 1);
    dataMap.put("b", 2);
    dataMap.put("c", 1);
    dataMap.put("d", 2);
    dataMap.put("e", 1);
    dataMap.put("f", 3);
    dataMap.put("g", 1);

    //main logic
    dataMap.forEach( (k,v) -> {
        if(countMap.get(v)==null)
            countMap.put(v, 0);
        Integer count=countMap.get(v);
        countMap.put(v,count+1);
    } );

    //printing the count
    countMap.forEach( (k,v) -> {
        System.out.println(k+"       "+v);
    } );

Upvotes: 0

Rishabh Kumar
Rishabh Kumar

Reputation: 557

For older JDKs you can count like this:

Create a class and override its equals() and hashcode() method. Create a field of your preferred type say A and add another int type field to count.
1) Your hashcode() method should return the hash value of your field A.
2) In your equals() method, increase the value of count by 1 and set the count as value

Now create 2 hashmaps, first will have your initial map's value as keys. The second one will have the result of all the counts of values.

Refer to the below snippet:

class A
{
   Integer count = 1;
   String name;

   @override
   public int hashcode()
   {
      return name.hash();
   }

   @override
   public boolean equals(Object obj)
   {
      obj.count++;   
      secondmap.put(obj.name, obj.count);         

      return true;
   }

}

Now in your main class:

static firstmap = new ConcurrentMap<A, Integer>();

static secondmap = new ConcurrentMap<String, Integer>();

iterate over yourmap
{
   put the value in firstmap as firstmap.put(yourmap value, 0);
}

At the end of iteration you will have all the count of values in the secondmap. Note: If your initial map was having different signature then you can explicitly set the value of String name via A's constructor.

This was just an example, the actual implementation may differ a bit according your solution however you can refer to this logic. Also while creating your initial map you can implement this. This will save you the trouble of iterating again.

Upvotes: 0

Josef Reichardt
Josef Reichardt

Reputation: 4296

You could do this much easier with the java 8 stream api.

For this you should take the values from your map: map.values()

With .stream() you get the stream for this collection.

then you can use the collect method with a groupingBy collector.

Finally it could look something like this:

final Map<Integer, Long> counts = map.values() // get the values
    .stream()                                  // get the stream
    .collect(
        Collectors.groupingBy(                 // the result should be grouped
            o -> o,                            // the key of the result map is just the value
            Collectors.counting()              // the value of result map is the count
        )
    );

Upvotes: 2

Related Questions