javaauto-value

How to add an element to the existing ImmutableSet - AutoValue?


Class Event {
  String eventName;
  Integer eventTime;
  ....
  // Event attributes with a builder
}

@AutoValue
public abstract class XYZ {

  public abstract ImmutableSet<Event> events();
  public abstract Event event();
  
  public static Builder builder() {
    return new AutoValue_XYZ.Builder();
  }

  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder setEvents(Set<Event> events);
    public abstract Builder setEvent(Event event);

    public abstract XYZ build();
  }
}

Usage: End user can add event as a single item or a set of items like below,

XYZ xyz = XYZ
    .builder()
    .setEvent(Event.builder().setEventName("event1").setEventTime(34324343).build())
    .setEvent(Event.builder().setEventName("event2").setEventTime(45324343).build())
    .setEvents(
        Set.of(Event.builder().setEventName("event3").setEventTime(55324343).build(),
                Event.builder().setEventName("event4").setEventTime(65324343).build())
    .build();

I would like to have all the event inputs in the events() Set, like everytime setEvent is used, add it to the main Set events(). How to achieve this?

Eg: xyz.events() should give 4 events in this case.


Solution

  • You can do this by:

    1. Using the AutoValue support for creating builders for collections
    2. Implementing helper functions on the builder
    @AutoValue
    public abstract class XYZ {
    
        public abstract ImmutableSet<Event> events();
    
        public static Builder builder() {
            return new AutoValue_XYZ.Builder();
        }
    
        @AutoValue.Builder
        public abstract static class Builder {
    
            public Builder addEvent(Event event) {
                eventsBuilder().add(event);
                return this;
            }
    
            public Builder addAllEvents(Iterable<? extends Event> events) {
                eventsBuilder().addAll(events);
                return this;
            }
    
            public abstract XYZ build();
    
            protected abstract ImmutableSet.Builder<Event> eventsBuilder();
        }
    }
    

    Optionally you can also make the eventsBuilder method public if you want to give direct access to the builder and not add the helper methods. The advantage of the helper methods is that they can return the XYZ.Builder and thus allow chaining.