code: public static <T, K, V> Collector<T, Map<K, V>, Map<K, V>> toUnmodifiableMap(
          Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) {
  
          BiConsumer<Map<K, V>, T> accumulator = (map, element) ->
              map.merge(keyMapper.apply(element), valueMapper.apply(element),
                  throwingMerger());
  
          return new UnmodifiableMapCollector<>(accumulator);
      }
docs: Method creates {@link UnmodifiableMapCollector} according to the {@code keyMapper} and {@code valueMapper}
  
  @param keyMapper {@link Function} that defines how to map a key in the map
  @param valueMapper {@link Function} that defines how to map a value in the map
  @param <T> the type of input elements to the reduction operation
  @param <K> the mutable accumulation type of the reduction operation (often hidden as an implementation detail)
  @param <V> the result type of the reduction operation
  @return unmodifiable-map collector