For mutable collections (the java.util ones supported by Singular), let @Singular create mutable collections instead of wrapping them in unmodifiable* or using empty* or singleton*.
It could be an option disabled by default, but accessible like this @Singluar(mutable = true).
It feels to me that being forced to go from mutable to immutable just by adding a convenience @Singular to a field is counterintuitive.
Or we can have the current behavior of creating immutable collections applied when the class is also marked as @Value, but have mutable collections otherwise a default.
Another take at this:
Currently it is not possible to mix @Singular with @Builder.Default which (I assume) is based on the fact that all Collections generated with @Singular are immutable, in which case an initialization with another Collection is not possible.
However the combination of @Singular with @Builder.Default could be used to allow arbitrary collection-types to be used with @Singular allowing even initializing the collection with default values:
Lombok
@Builder
class ExampleWithSingularAndDefault<T> {
@Singular @Default private List<T> children = new ArrayList<T>();
@Singular @Default private List<T> childrenWithDefaults =
ExampleWithSingularAndDefault.generateDefaultChildren();
@Singular @Default private Set<T> childrenAsTreeSet = new TreeSet<T>();
@Singular private List<T> childrenWithImmutableList;
}
Vanilla
class ExampleWithSingularAndDefault<T> {
private List<T> children = new ArrayList<T>();
private List<T> childrenWithDefaults =
ExampleWithSingularAndDefault.generateDefaultChildren();
private Set<T> childrenAsTreeSet = new TreeSet<T>();
private List<T> childrenWithImmutableList;
/*
* Builder code generated without any change
* (in the end the AllArgsConstructor is called with immutable collections)
*/
public BuilderSingularLists(
List<T> children, List<T> childrenWithDefaults,
Set<T> childrenAsTreeSet, List<T> childrenWithImmutableList) {
if(this.children == null) {
// Default value is not available → act like the available implementation
this.children = children;
} else {
// Add the values from the builder to the generated defaults
this.children.addAll(children);
}
// handle the other collections identically
if(this.childrenWithDefaults == null) {
this.childrenWithDefaults = childrenWithDefaults;
} else {
this.childrenWithDefaults.addAll(childrenWithDefaults);
}
if(this.childrenAsTreeSet == null) {
this.childrenAsTreeSet = childrenAsTreeSet;
} else {
this.childrenAsTreeSet.addAll(childrenAsTreeSet);
}
// handle like before if @Default is not defined
this.childrenWithImmutableList = childrenWithImmutableList;
}
}
As I am quite new to this project: Has a solution like this already been discussed? Have I missed some major pitfalls with @Singular and @Default?
Or we can have the current behavior of creating immutable collections applied when the class is also marked as
@Value, but have mutable collections otherwise a default.
I REALLY like the first suggestion of adding an optional (mutable = true) parameter to the Singular annotation. But changing default behavior in a widely used library is not something I would ever encourage.
Any update on this please! I believe this is crucial feature that Lombok team should consider.
Thank You guys for letting me know that im not the only one that wish to have this kind of feature with Lombok.
Creating mutable collection at the moment results in bad looking code.
I spend hours on trying to figure it out how to do this better with Lombok and found this thread.
We are in dire need of this feature right now. I understand the advantages of immutable collections in certain scenarios, but the practical advantages of mutable collections are often more important in real world projects.
There are a ton of complications if these things become mutable. We'd have to explain all this, add a sizable maintenance burden, which makes this feature fall under overgrowth of annotation parameters.
Sorry folks. We're not going to do this, and would not accept a PR.
Thank you rzwitserloot for your reply.
I understand that I don't get all the implications of adding this feature.
Good luck continuing work on this beautiful project.
Cheers
Most helpful comment
Another take at this:
Currently it is not possible to mix
@Singularwith@Builder.Defaultwhich (I assume) is based on the fact that all Collections generated with@Singularare immutable, in which case an initialization with another Collection is not possible.However the combination of
@Singularwith@Builder.Defaultcould be used to allow arbitrary collection-types to be used with@Singularallowing even initializing the collection with default values:Lombok
Vanilla
As I am quite new to this project: Has a solution like this already been discussed? Have I missed some major pitfalls with
@Singularand@Default?