Why is MapWithDefault private?

I like to use .withDefault on maps. Today I wanted to write a class containing some mapping of values and wanted to be sure every instance of such class will also define a default mapping. Example of such mapping:

mapOf(
  "w" to Gender.FEMALE,
  "m" to Gender.MALE,
  "u" to Gender.UNKNOWN
).withDefault { Gender.UNKNOWN }

The simple idea to ensure that default value for the map is always set was to use MapWithDefault as the type of my property:

val genderMapping: MapWithDefault<String, Gender>

But both implementation and interface for MapWithDefault are private so I cannot access it. Why is that? I would expect at least interface to be public.
In current situation I cannot evaluate easily if my map is MapWithDefault and there is also no way to see if the default value was set.

1 Like

I have mixed feelings. MapWithDefault does not provide new capabilities and usually we shouldn’t create new types for specific types of behavior - they should be part of implementation details.

However, there are some exceptions of this rule, for example immutable collections. Knowledge that the collection is immutable allows to perform new kind of operations on it, even if it doesn’t provide any new functionality itself. In Scala and kotlinx.collections.immutable there are specific types. In Java we only have unmodifiable*() functions and these implementations are unrecognizable from regular collections.

Even if we go this direction and say this kind of map should be represented as a separate type, I don’t like to go with MapWithDefault. This class/interface clearly references the behavior, not capabilities. I think it would make sense to create a subtype of Map which guarantees to return something from get(). Then MapWithDefault would be one of its implementations.

3 Likes