@Contract(pure = true)
  public @NotNull UnmodifiableHashMap<K, V> with(@NotNull K key, @Nullable V value) {
    int pos = data.length == 0 ? -1 : tablePos(strategy, data, key);
    if (pos >= 0) {
      if (data[pos + 1] == value) return this;
      Object[] copy = data.clone();
      copy[pos + 1] = value;
      return new UnmodifiableHashMap<>(strategy, copy, k1, v1, k2, v2, k3, v3);
    }
    if (k1 == null) {
      return new UnmodifiableHashMap<>(strategy, data, key, value, null, null, null, null);
    }
    if (strategy.equals(k1, key)) {
      return value == v1 ? this : new UnmodifiableHashMap<>(strategy, data, k1, value, k2, v2, k3, v3);
    }
    if (k2 == null) {
      return new UnmodifiableHashMap<>(strategy, data, k1, v1, key, value, null, null);
    }
    if (strategy.equals(k2, key)) {
      return value == v2 ? this : new UnmodifiableHashMap<>(strategy, data, k1, v1, k2, value, k3, v3);
    }
    if (k3 == null) {
      return new UnmodifiableHashMap<>(strategy, data, k1, v1, k2, v2, key, value);
    }
    if (strategy.equals(k3, key)) {
      return value == v3 ? this : new UnmodifiableHashMap<>(strategy, data, k1, v1, k2, v2, k3, value);
    }
    Object[] newData = new Object[(size + 1) * 4];
    for (int i = 0; i < data.length; i += 2) {
      @SuppressWarnings("unchecked") K k = (K)data[i];
      if (k == null) continue;
      Object v = data[i + 1];
      insert(strategy, newData, k, v);
    }
    insert(strategy, newData, k1, v1);
    insert(strategy, newData, k2, v2);
    insert(strategy, newData, k3, v3);
    insert(strategy, newData, key, value);
    return new UnmodifiableHashMap<>(strategy, newData, null, null, null, null, null, null);
  }
@Contract(pure = true)
  public @NotNull UnmodifiableHashMap<K, V> with(@NotNull K key, @Nullable V value)