将AutoValue中的不可变映射键替换为toBuilder()



我在将AutoValue与geneated Builder和字段与Guava ImmutableMap一起使用时遇到了一个问题。

假设我们有这个容器价值类别:

public abstract class Container {

public abstract ImmutableMap<String, String> metadata();
public abstract Builder toBuilder();
public static Builder builder() {
return new AutoValue_Container.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract ImmutableMap.Builder<String, String> metadataBuilder();

public final Builder addMetadata(String key, String value)  {
metadataBuilder().put(key, value);
return this;
}
}
}

当我想执行以下操作时,ImmutableMap构建器会抛出java.lang.IllegalArgumentException: Multiple entries with same key

aContainer.toBuilder().addMetadata("existingKey", "someNewValue");

熟悉AutoValue的人知道如何说服实现按要求执行吗?

在构建者的howto文档中有一个文档化的解决方法。报价:

@AutoValue
public abstract class Foo {
public abstract ImmutableMap<Integer, String> map();
...
@AutoValue.Builder
public abstract static class Builder {
private final ImmutableMap.Builder<Integer, String> mapBuilder = ImmutableMap.builder();
public ImmutableMap.Builder<Integer, String> mapBuilder() {
return mapBuilder;
}
abstract Builder setMap(ImmutableMap<Integer, String> map); // not public
abstract Foo autoBuild(); // not public
public Foo build() {
setMap(mapBuilder.buildKeepingLast());
return autoBuild();
}
...
// #start
// Needed only if your class has toBuilder() method
public Builder toBuilder() {
Builder builder = autoToBuilder();
builder.mapBuilder().putAll(map());
return builder;
}
abstract Builder autoToBuilder(); // not public
// #end
}
}

最新更新