2015-12-11 11 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を直接バイパスしようとする可能性があります、それはここの唯一のオプションですか?

答えて

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

AutoValueには、Guavaのimmutable collectionsを使用するときに再生される特殊な機能がいくつかあります。これらのコレクションはすべて、それぞれに関連するBuilderタイプを持っているからです。

1つの特徴は、抽象的なcardsBuilder()メソッドを定義して、適切なコレクションタイプの新しいビルダーを開始し、それを元に戻すということです(もちろん、値クラスのプロパティを変更できないようにする必要があります)。呼び出し側。これは超柔軟ですが、それについての一つの悲しいことは、 "鎖を壊す"ということです。発信者は現在ImmutableList.Builderで電話をかけており、に戻ってbuildに電話をかけることはできません。

しかし、上記のように独自のaddCardメソッドを追加して、それを実装してcardsBuilder().add(card)を呼び出してから、thisをビルダーの代わりに返すように実装することができます。問題が解決しました!

この機能は1.1で機能するはずですが、問題がある場合はお知らせください。

P.S.私はお詫び申し上げます - いくつかの技術的な問題のために公開サイトにプッシュされているのを防ぐために、このトピックを含むAutoValueユーザーガイドの新しい資料がたくさんあります。

+2

は、同じ機能を持たないために計画はありますcom.google.common.collectビルダーのみですが、ビルダーはどれですか?私は生成されたビルダーのために同じ機能を使用したいです! – oae

関連する問題