private static <K, V> @NotNull Index<K, V> create(final List<V> values, final IntFunction<Map<V, K>> valueToKeyFactory, final @NotNull Function<? super V, ? extends K> keyFunction) {
    final int length = values.size();
    final Map<K, V> keyToValue = new HashMap<>(length);
    final Map<V, K> valueToKey = valueToKeyFactory.apply(length); // to support using EnumMap instead of HashMap when possible
    for (int i = 0; i < length; i++) {
      final V value = values.get(i);
      final K key = keyFunction.apply(value);
      if (keyToValue.putIfAbsent(key, value) != null) {
        throw new IllegalStateException(String.format("Key %s already mapped to value %s", key, keyToValue.get(key)));
      }
      if (valueToKey.putIfAbsent(value, key) != null) {
        throw new IllegalStateException(String.format("Value %s already mapped to key %s", value, valueToKey.get(value)));
      }
    }
    return new Index<>(Collections.unmodifiableMap(keyToValue), Collections.unmodifiableMap(valueToKey));
  }
Creates an index map.

@param keyFunction the key function
@param constants the constants
@param <K> the key type
@param <V> the value type
@return the key map
@since 4.0.0
api/src/main/java/net/kyori/adventure/util/Index.java