I'm creating a poker rank solver and I have to count cards with same suit or same rank in a set of cards. Here I create HashMap
and increment value if multiple ranks are in the set.
private boolean isFourOfAKind() {
Map<RANK, Integer> rankDuplicates = new HashMap<>();
for(Card card : cards) {
rankDuplicates.put(card.getRank(), rankDuplicates.getOrDefault(card.getRank(), 0) + 1);
}
return rankDuplicates.containsValue(4);
}
I was wondering is it possible using streams do exact same things with java streams. It would look something like this:
private boolean isFourOfAKind() {
Map<RANK, Integer> rankDuplicates = cards.stream()
.map(Card::getRank)
.collect(Collectors.toMap(/*...something goes here..*/)); // of course this is very wrong, but you can see what I'm aiming at.
return rankDuplicates.containsValue(4);
}
It looks like you are looking for something like
return cards.stream()
.collect(Collectors.toMap(Card::getRank, e -> 1, Integer::sum))
// keyMapper, valueMapper, mergeFunction
.containsValue(4);
Another variant with groupingBy
:
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
...
private boolean isFourOfAKind() {
return cards.stream()
.collect(groupingBy(Card::getRank, counting()))
.containsValue(4L);
}
Basically you group the card by the ranks so that you have a Map<Rank, List<Card>>
Then you use the downstream collector counting()
to map each list to its number of elements, so that the final result is a Map<Rank, Long>
(you could also use summingInt(i -> 1)
instead of counting()
if you really need to have a Map<Rank, Integer>
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With