Odd "type mismatch" with `mapNotNullTo`

Hi all, any idea why this compiles:

fun <T, K> Collection<T>.getDuplicates(keySelector: (T) -> K): Set<T> =
    if (this is Set) emptySet() else groupBy(keySelector).values.filter { it.size > 1 }.mapTo(mutableSetOf()) { it.first() }

but when I try to combine the filter and mapTo via mapNotNullTo I get a "type mismatch: required any but found T":

fun <T, K> Collection<T>.getDuplicates(keySelector: (T) -> K): Set<T> =
    if (this is Set) emptySet() else groupBy(keySelector).values.mapNotNullTo(mutableSetOf()) { occurrences -> occurrences.first().takeIf { occurrences.size > 1 } }

This is because mapNotNullTo() specifies that it returns a collection of not-null items. In your example T may be nullable and this is why it does not compile.

Also, your second example handles nulls incorrectly - even if there are multiple nulls values, they are not detected as duplicates and simply ignored. If you prefer to disallow nulls in the source collection, just define T as T : Any and both problems will be gone.

2 Likes

Thanks. I continue to forget that also T can be nullable, not only T?