Search code examples
javaauto-value

Is it possible to add a value to a collection in Java AutoValue?


I have a Java AutoValue class with a List attribute. I'd like to allow the builder to append to the List rather than having to pass the entire constructed list.

Example:

import com.google.auto.value.AutoValue;
@AutoValue
public abstract class Deck {
    public abstract List<Card> cards();
    public static Builder builder() {
        return new AutoValue_Card.Builder()
            .cards(new ArrayList<Card>());
    }
    @AutoValue.Builder
    public abstract static class Builder {
        public abstract Builder cards(List<Card> cards);
        /**
         * Append card to cards in the constructed Deck.
         */
        public Builder addCard(Card card) {
            // Is it possible to write this function?
        }
    }
}

What's the best solution for writing the addCard function? Does AutoValue somehow support this already? The intermediate cards property in the constructed class not visible to the Builder so I can't access it directly. I could try to bypass the Builder directly by keeping my own copy of cards in the Builder, is that the only option here?


Solution

  • In case someone finds it useful - here is the actual code of what I assume Kevin suggested. It was not obvious when I first stumbled upon his reply, so here you go:

    import com.google.auto.value.AutoValue;
    import com.google.common.collect.ImmutableList;
    
    @AutoValue
    public abstract class Hand {
      public static Builder builder() {
        return new AutoValue_Hand.Builder();
      }
    
      public abstract Builder toBuilder();
    
      public abstract String name();
    
      public abstract ImmutableList<String> cards();
    
      @AutoValue.Builder
      public static abstract class Builder {
    
        public abstract Builder name(String name);
    
        protected abstract ImmutableList.Builder<String> cardsBuilder();
    
        public Builder addCard(String card) {
          cardsBuilder().add(card);
          return this;
        }
    
        public abstract Hand build();
      }
    }
    

    Usage:

    Hand fullHouseHand = Hand.builder()
        .name("Full House")
        .addCard("King")
        .addCard("King")
        .addCard("King")
        .addCard("10")
        .addCard("10")
        .build();
    System.out.print(fullHouseHand);
    

    Output:

    Hand{name=Full House, cards=[King, King, King, 10, 10]}