lombokを使用して既存のオブジェクトからオブジェクトを構築します


105

次のようなlombokアノテーション付きクラスがあるとしましょう

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

私は私ができることを知っています:

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

既存のオブジェクトをテンプレートとして使用し、そのプロパティの1つを変更して、Fooのオブジェクトを作成する簡単な方法はありますか?

何かのようなもの:

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

これはlombokのドキュメントでは見つかりません。

回答:


232

toBuilderパラメータを使用して、インスタンスにtoBuilder()メソッドを与えることができます。

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

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

ドキュメントから:

@Builderを使用してビルダーを生成し、独自のクラスのインスタンスを生成する場合(独自の型を返さないメソッドに@Builderを追加しない限り、これは常に当てはまります)、@ Builder(toBuilder = true)を使用して生成することもできます。 toBuilder()と呼ばれるクラスのインスタンスメソッド。このインスタンスのすべての値で始まる新しいビルダーを作成します。

免責事項:私はlombok開発者です。


12
@Mustafaもあります@Wither。これは、単一フィールドの変更に対してより効率的ですFoo f1 = f0.withX(42)
maaartinus 2017年

@maaartinus@Witherは、既存のオブジェクトのフィールドを設定する代わりに、常に新しいオブジェクトを返すwith *メソッドを生成すると思います。これは効率が低いです。
MGhostSoft

3
@MGhostSoft私は明らかに、新しいオブジェクトを作成することが目標であると想定しています。したがって、不変オブジェクトがますます使用されるため、私たちはかなり一般的です。++×単一のフィールドを変更するに@Witherは、最適です。2つ以上のFot、toBuilder勝ちます。以下の私の答えを参照してください。
maaartinus

2
また、フィールドがゼロの場合(つまり、変更なしのオブジェクトコピー)、@Witherまったく機能しませんが、機能します.toBuilder().build()
M.ジャスティン

40

既存のオブジェクトをテンプレートとして使用し、そのプロパティの1つを変更して、Fooのオブジェクトを作成する簡単な方法はありますか?(強調鉱山

本当に単一のプロパティを変更したい場合は、より優れた、より効率的な方法があります。

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

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

枯れはゴミを生成しませんが、1つのフィールドのみを変更できます。多くのフィールドを変更するには、

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

大量のゴミを生成しますが(すべて中間結果)、toBuilderより効率的で自然です。

注:古いバージョンのlombokは@Wither注釈を使用していました。ドキュメントの冒頭を参照してください。


1
本当にそんなにゴミが出るのでしょうか?置き換えるフィールドを除いて、すべて浅いコピーだと思います(意図されている場合は、オブジェクトを既に不変にするという概念に依存しています)。「ガベージ」は、ほとんどの場合、破棄された最上位オブジェクトの参照になります(ただし、プリミティブが多いと、ガベージも増える可能性があります)。
jm0

1
@ jm0確かに、それはすべて浅いコピーです。「大量のゴミ」とはn-1、への一連のn呼び出しのオブジェクトを意味しますwithSomething。オブジェクトのコストは、数バイトに加えて、参照ごとに4または8バイトに加えて、プリミティブごとに1〜8バイトのようなものです。つまり、呼び出しごとに数十バイトについて話しているのです。通常、大したことはありません。
maaartinus
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.