2015-12-11 27 views
8

我有一個帶有List屬性的Java AutoValue類。我希望允許構建器追加到列表中,而不必傳遞整個構建的列表。是否可以向Java AutoValue中的集合添加值?

例子:

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? 
     } 
    } 
} 

什麼是用於編寫addCard功能的最佳解決方案? AutoValue已經以某種方式支持它了嗎?構造類中的中間卡屬性對Builder不可見,所以我無法直接訪問它。我可以通過在Builder中保留自己的副本來嘗試繞過Builder,這是唯一的選擇嗎?

回答

3

如果有人發現它有用 - 這裏是我認爲凱文建議的實際代碼。這不是明顯,當我第一次無意中發現他的回覆,所以在這裏你去:

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(); 
    } 
} 

用法:

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

輸出:

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

當您使用Guava的immutable collections時,AutoValue具有一些特殊功能,因爲這些集合都有其自己的關聯生成器類型。 (當然,你當然希望你的值類的屬性是不可改變的!)

一個特性是你可以定義一個摘要cardsBuilder()方法,它將啓動一個適當集合類型的新構建器並將其返回給呼叫者,召集者。這是超級靈活的,但最讓人傷心的是它「打破了連鎖」。來電者正在撥打電話ImmutableList.Builder,無法返回Deck.Builder撥打build

但是你可以解決通過添加自己的addCard方法,就像你在前面已經表明它,只是實現它調用cardsBuilder().add(card),然後返回this而不是建設者。問題解決了!

我相信所有這些應該在1.1功能,但請讓我們知道,如果你有麻煩!

P.S.我很抱歉 - 我們爲AutoValue用戶指南提供了大量新內容,包括這個主題,由於一些技術上的困難,這些內容一直在被推送到公共場所。

+2

是具有相同的功能不是有計劃僅適用於com.google.common.collect構建器,但適用於任何構建器?我很樂意爲我生成的構建器使用相同的功能! – oae

相關問題