Lombok kullanarak mevcut bir nesneden bir nesne oluşturun


102

Diyelim ki lombok açıklamalı bir sınıfım var.

@Builder
class Band {
   String name;
   String type;
}

Yapabileceğimi biliyorum:

Band rollingStones = Band.builder().name("Rolling Stones").type("Rock Band").build();

Mevcut nesneyi şablon olarak kullanarak Foo nesnesini oluşturmanın ve özelliklerinden birini değiştirmenin kolay bir yolu var mı?

Gibi bir şey:

Band nirvana = Band.builder(rollingStones).name("Nirvana");

Bunu lombok belgelerinde bulamıyorum.

Yanıtlar:


225

toBuilderÖrneklerinize bir toBuilder()yöntem vermek için parametreyi kullanabilirsiniz .

@Builder(toBuilder=true)
class Foo {
   int x;
   ...
}

Foo f0 = Foo.builder().build();
Foo f1 = f0.toBuilder().x(42).build();

Gönderen belgeler :

Kendi sınıfınızın örneklerini üretmek için derleyiciler oluşturmak için @Builder kullanıyorsanız (kendi türünüzü döndürmeyen bir yönteme @ Builder eklemediğiniz sürece bu her zaman geçerlidir), ayrıca oluşturmak için @Builder (toBuilder = true) kullanabilirsiniz. sınıfınızdaki toBuilder () adında bir örnek yöntemi; bu örneğin tüm değerleri ile başlayan yeni bir oluşturucu yaratır.

Sorumluluk reddi: Ben bir lombok geliştiricisiyim.


11
@Mustafa da var @Withertek alan değişiklikleri için daha verimli olan: Foo f1 = f0.withX(42).
maaartinus

@maaartinus Bence @Withervar olan nesnenin alanını ayarlamak yerine her zaman yeni bir nesne döndüren * yöntemlerle üretiyor. Bu düşük verimlidir.
MGhostSoft

2
@MGhostSoft Açıkçası yeni bir nesne yaratmanın asıl hedef olduğunu varsayıyorum. Bu nedenle, değişmez nesneler gittikçe daha fazla kullanıldığı için oldukça yaygınız. ++ × Tek bir alanı değiştirmek için @Witheren iyisidir. İkiden fazla ise toBuilderkazanır. Aşağıdaki cevabıma bakın.
maaartinus

2
Ve sıfır alanlar için (yani, herhangi bir değişiklik olmadan bir nesne kopyası), @Witherhiç çalışmaz, çalışır .toBuilder().build().
M. Justin

38

Mevcut nesneyi şablon olarak kullanarak Foo nesnesini oluşturmanın ve özelliklerinden birini değiştirmenin kolay bir yolu var mı ? ( vurgu benim )

Tek bir mülkü gerçekten değiştirmek istiyorsanız, daha güzel ve daha verimli bir yol var:

@With
class Band {
   String name;
   String type;
}

Band nirvana = rollingStones.withName("Nirvana");

Kuruyanlar çöp oluşturmaz, ancak yalnızca tek bir alanı değiştirebilir. Birçok alanı değiştirmek için kullanabilirsiniz

withA(a).withB(b).withC(c)....

ve tonlarca çöp üretir (tüm ara sonuçlar), ancak bundan toBuilderdaha verimli ve daha doğaldır.

NOT: lombok'un eski sürümlerinde @Witheraçıklama kullanılmıştır . Belgelerin başlangıcına bakın .


1
gerçekten bu kadar çöp yaratır mı? Sanırım, değiştirdiğiniz alan haricinde hepsi sığ kopyalar (amaçlanan buysa, nesneyi zaten değişmez hale getireceğiniz fikrine dayanarak). "Çöp", çoğunlukla atılan üst düzey nesnenin başvuruları olacaktır (yine de birçok ilkel öğenin daha fazla çöp ile sonuçlanabileceğini tahmin ediyorum).
jm0

1
@ jm0 Elbette, hepsi sığ kopyalar. "Tonlarca çöp" n-1ile bir dizi nçağrı için nesneleri kastettim withSomething. Bir nesnenin maliyeti birkaç bayt artı referans başına 4 veya 8 bayt artı ilkel başına 1 ila 8 bayttır. Yani arama başına onlarca bayttan bahsediyoruz. Genellikle önemli değil.
maaartinus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.