You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 16, 2024. It is now read-only.
#306 Specialised support for lists of buildable objects
Combine existing support for list properties and buildable properties. A list of buildable objects will now get:
* versions of all add methods that accept Builders
* late calling of the build() methods
* cascading of buildPartial()
* getter and mutator exposing a list of builders rather than a list of values
* lazy conversion of immutable instances to builders
FreeBuilder has special support for lists of buildable types, too. It maintains
447
+
a list of builders, to allow elements of the list to be built incrementally. (For
448
+
better performance, if given a built instance for the list, it will lazily convert
449
+
it to a Builder on demand. This may cause problems if your buildable types
450
+
continue to be mutable after construction; to avoid unpredictable aliasing,
451
+
we recommend disabling buildable list support, as described below.)
452
+
453
+
A list of buildable properties called 'owners' would generate:
454
+
455
+
| Method | Description |
456
+
|:------:| ----------- |
457
+
|`addOwners(Person element)`| Appends `element` to the collection of owners. Throws a NullPointerException if element is null. The element may be lazily converted to/from a Builder. |
458
+
|`addOwners(Person.Builder builder)`| Appends the value built by `builder` to the collection of owners. Throws a NullPointerException if builder is null. Only a copy of the builder will be stored; changes made to it after this method returns will have no effect on the list. The copied builder's `build()` method will not be called immediately, so if this builder's state is not legal, you will not get failures until you build the final immutable object. |
459
+
|`addOwners(Person... elements)`| Appends all `elements` to the collection of owners. Throws a NullPointerException if elements, or any of the values it holds, is null. Each element may be lazily converted to/from a Builder. |
460
+
|`addOwners(Person.Builder... builders)`| Appends the values built by `builders` to the collection of owners. Throws a NullPointerException if builders, or any of the values it holds, is null. Only copies of the builders will be stored, and `build()` methods will not be called immediately. |
461
+
|`addAllOwners(Iterable<Person> elements)`<br>`addAllOwners(Stream<Person> elements)`<br>`addAllOwners(Spliterator<Person> elements)`| Appends all `elements` to the collection of owners. Throws a NullPointerException if elements, or any of the values it holds, is null. Each element may be lazily converted to/from a Builder. |
462
+
|`addAllBuildersOfOwners(Iterable<Person.Builder> builders)`<br>`addAllBuildersOfOwners(Stream<Person.Builder> builders)`<br>`addAllBuildersOfOwners(Spliterator<Person.Builder> builders)`| Appends the values built by `builders` to the collection of owners. Throws a NullPointerException if builders, or any of the values it holds, is null. Only copies of the builders will be stored, and `build()` methods will not be called immediately. |
463
+
|`mutateOwners(Consumer<? super List<Person.Builder>> mutator)`| Invokes the [Consumer]`mutator` with the list of owner builders. Throws a NullPointerException if `mutator` is null. As `mutator` is a void consumer, any value returned from a lambda will be ignored, so be careful not to call pure functions like [stream()] expecting the returned collection to replace the existing collection. |
464
+
|`clearOwners()`| Removes all elements from the collection of owners, leaving it empty. |
465
+
|`buildersOfOwners()`| Returns an unmodifiable view of the list of owner builders. Changes to the list held by the builder will be reflected in the view, and changes made to any of the returned builders will be reflected in the final list of owners. |
466
+
467
+
Note that `mutateOwners` and `buildersOfOwners` are the only methods which can cause lazy convertion of an inserted value to a Builder, and then only upon accessing the element, so avoid these actions if possible to avoid unexpected performance hits.
468
+
469
+
#### Disabling buildable lists
470
+
471
+
You can force FreeBuilder to use vanilla list support, rather than converting elements
472
+
to/from Builders under the hood, by declaring a vanilla getter in the Builder. For
473
+
instance, to force `owners` to drop Builder support:
474
+
475
+
```java
476
+
classBuilderextendsFoo_Builder {
477
+
@Override
478
+
publicList<Person>owners() {
479
+
// Disable FreeBuilder's lazy conversion to/from Person.Builder by declaring
480
+
// a non-Builder-compatible getter.
481
+
returnsuper.owners();
482
+
}
483
+
}
484
+
```
485
+
486
+
FreeBuilder will now generate the methods described in [Collections and Maps](#collections-and-maps).
487
+
488
+
440
489
### Custom toString method
441
490
442
491
FreeBuilder will only generate toString, hashCode and equals methods if they are left abstract, so to customise them, just implement them.
@@ -672,9 +721,16 @@ directory** setting) and select **Mark Directory As > Generated Sources Root**.
FreeBuilder 2.1 adds more extensive API customization for [lists of buildable types](#lists-of-buildable-types), storing Builder instances internally until build is called, cascading buildPartial automatically, and adding overloads accepting Builder instances.
730
+
731
+
This is a behavioural and, for the get and mutate methods, a non-binary-backwards-compatible change. If you have existing properties that you do not want this to affect, see [disabling buildable lists](#disabling-buildable-lists) for instructions on restoring the 2.0 behaviour on a case-by-case basis.
732
+
733
+
### Upgrading from v1
678
734
679
735
There are three API-breaking changes between v1 and v2 of FreeBuilder:
0 commit comments