2015-12-11 31 views
8

Liste özniteliğine sahip bir Java AutoValue sınıfım var. Oluşturucunun, tüm oluşturulmuş listeyi geçmek zorunda kalmak yerine Listeye eklemesine izin vermek istiyorum.Java AutoValue'da bir koleksiyona değer eklemek mümkün mü?

Örnek:

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 fonksiyonunu yazmak için en iyi çözüm nedir? AutoValue bir şekilde bunu zaten destekliyor mu? Oluşturulan sınıftaki ara kartlar özelliği, Oluşturucu tarafından görülemez, dolayısıyla doğrudan erişemiyorum. Builder'daki kartların kopyasını kendime saklayarak Builder'ı baypas etmeyi deneyebilirim, buradaki tek seçenek bu mu?

cevap

3

Birisi bunu yararlı buluyorsa - burada Kevin'ın önerdiği şeylerin gerçek kodu. Önce onun cevapta tökezledi zaman belirgin değildi, işte gidip:

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

Kullanımı:

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

Çıktı:

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

AutoValue, Guava'nın immutable collections kullandığınızda devreye giren birkaç özel özelliğe sahiptir, çünkü bu koleksiyonların hepsinin ilişkili oluşturucu türleri vardır. (Ve tabii ki, kesinlikle değer sınıflarınızın özelliklerinin değişmez olmasını istersiniz!)

Tek bir özellik, uygun koleksiyon tipinin yeni oluşturucusunu başlatacak ve onu geri gönderecek olan bir cardsBuilder() yöntemini tanımlayabilirsiniz. arayan. Bu süper esnek, ama bu konuda üzücü olan şey, "zinciri bozuyor". Arayan şimdi ImmutableList.Builder numaralı telefondan arama yapıyor ve build'u aramak için Deck.Builder'a geri dönemeyiz.

Ama bunu yukarıdan gösterdiğin gibi, kendi addCard yöntemi ekleyerek bu ele alır ve sadece cardsBuilder().add(card) arayıp sonra yerine oluşturucu this döndürecek şekilde uygulayabilir. Sorun çözüldü!

Tüm bunların 1.1'de işlevsel olması gerektiğine inanıyorum, ancak sorun çıkarırsanız lütfen bize bildirin!

P.S. Özür dilerim - bu konu da dahil olmak üzere AutoValue kullanıcı kılavuzu için, birkaç teknik sıkıntı nedeniyle kamuya yayılmakta olan bir çok yeni malzemeye sahibiz.

+2

aynı işlevselliği olmayan sahibi olmak için planlar var Sadece com.google.common.collect geliştiricileri için ancak herhangi bir oluşturucu için mi? Oluşturduğum inşaatçılar için aynı işlevselliği kullanmayı çok isterim! – oae