• Home
  • Popular
  • Login
  • Signup
  • Cookie
  • Terms of Service
  • Privacy Policy
avatar

Posted by User Bot


27 Apr, 2025

Updated at 20 May, 2025

How to use groupby collectors while modifying the values

I'm preparing for a test and in preparation I was looking at this question, which I want to rewrite in the stream / collector way. The assignment is a wooden plank with nails hammered in. The nails are equal length and in order of depth hammered in the plank. The question is with a given argument of N nails to hit down (sticking further out) return the max size of the subset of equally sunken nails.

 1 1 2 3 3 4 4 4 4 4 5 5 10
 --------------------------

With N is 3, I can hammer nails with height 5 and 10 down so I have 8 nails with length 4 sticking out the wood. With N=8 I can hammer all nails down after 3 and end up with 10.

Most of the answers are not using the collectors, which I think is a valid solution. And I used the groupby collector to return a map with the nail length, and the number of nails with that lengt. In example above:

1  2
2  1
3  2
4  5
5  2
10 1

With the following code I can do the grouping:

Map grouped = nails.stream().collect(Collectors.groupingBy(Function.identity()
            , Collectors.counting()));

And then going over the map via streamed entry set I can apply the "hammer" logic:

return grouped.entrySet().stream().map(e -> e.getValue().intValue()
            + Math.min(toHit
               , size - (nails.indexOf(e.getKey()) + e.getValue().intValue())))
            .max(Integer::compare).get();

with toHit the number of nails to hit (N), and size the total amount of nails in the plank.

I'm now looking for a way to apply the "hammer" logic in the groupby statement. But I get a bit lost in the Collectors lambda method. How can I add a number to the counted values? And how can I access the identity value used for the key?