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?