私はマルチスレッドアプリケーションから使用しているビルダークラスを持っていますので、スレッドセーフにしました。簡単にするために、ここでは問題を示すためのフィールドをいくつか示しています。同じキー不変マップエラーの複数のエントリ
public final class ClientKey {
private final long userId;
private final int clientId;
private final String processName;
private final Map<String, String> parameterMap;
private ClientKey(Builder builder) {
this.userId = builder.userId;
this.clientId = builder.clientId;
this.processName = builder.processName;
// initializing the required fields
// and below line throws exception once I try to clone the `ClientKey` object
builder.parameterMap.put("is_clientid", (clientId == 0) ? "false" : "true");
this.parameterMap = builder.parameterMap.build();
}
public static class Builder {
private final long userId;
private final int clientId;
private String processName;
private ImmutableMap.Builder<String, String> parameterMap = ImmutableMap.builder();
// this is for cloning
public Builder(ClientKey key) {
this.userId = key.userId;
this.clientId = key.clientId;
this.processName = key.processName;
this.parameterMap =
ImmutableMap.<String, String>builder().putAll(key.parameterMap);
}
public Builder(long userId, int clientId) {
this.userId = userId;
this.clientId = clientId;
}
public Builder parameterMap(Map<String, String> parameterMap) {
this.parameterMap.putAll(parameterMap);
return this;
}
public Builder processName(String processName) {
this.processName = processName;
return this;
}
public ClientKey build() {
return new ClientKey(this);
}
}
// getters
}
以下は、ClientKey
の作り方です。正常に動作します。以下に示すように
Map<String, String> testMap = new HashMap<String, String>();
testMap.put("hello", "world");
ClientKey keys = new ClientKey.Builder(12345L, 200).parameterMap(testMap).build();
は今、私はそれが例外をスローし、keys
オブジェクトのクローンを作成しようとします。
ClientKey clonedKey = new ClientKey.Builder(keys).processName("hello").build();
ように、それはエラーメッセージと例外をスローします:どのように私はこの問題を解決することができますjava.lang.IllegalArgumentException: Multiple entries with same key: is_clientid=true and is_clientid=true
builder.parameterMap.put("is_clientid", (clientId == 0) ? "false" : "true");
// from below line exception is coming
this.parameterMap = builder.parameterMap.build();
?私はマップを不変にしたいと思っていますが、私はまた、必要なフィールドでも初期化したいと思います。それは、ClientKey
クラスのコンストラクタでのみ行うことができます。 ClientKey
オブジェクトのクローン作成中に例外がスローされます。
エラーメッセージがスローされる場所を明確にすることはできますか? 'ClientKey clonedKey = new ClientKey.Builder(keys).processName(" hello ")。build();'キーを持っていなくても例外をスローする 'is_clientid '。コードの次の行はどこで起こっていますか? – jamesw1234
これは本当にビルダーパターンのインスタンスですか? - 私は誰かが新しいオブジェクトのフィールドを設定するために専用のコンストラクタに "ビルダー"を渡すことはありませんでした。 – errantlinguist
@ keys_1234例外はこの '' this.parameterMap = builder.parameterMap.build(); 'であり、' keys'オブジェクトを新しい 'clonedKey'にクローンしようとした場合にのみスローされます –