不変リストを別の不変リストに変換するためのワンライナーGuavaソリューションが必要だと思いますが、それが見つかりません。次のオブジェクトがあるとします。
ImmutableList<String> input = ImmutableList.of("a", "b", "c");
Function<String, String> function = new Function<String, String>() {
@Override
public String apply(String input) {
return input + input;
}
};
変換は次のように実行できます。
Iterable<String> transformedIt = Iterables.transform(input, function);
ImmutableList<String> output = ImmutableList.<String>builder().addAll(transformedIt).build();
またはこのように:
List<String> transformedList = Lists.transform(input, function);
ImmutableList<String> output2 = ImmutableList.copyOf(transformedList);
しかし、この種の変換には、パフォーマンスが最適化されたワンライナーがどこかにあるはずだと思います。中間オブジェクトがなければ、それを見つけることができません。それはどこにある?
ビルダーを削除してインライン化するだけで、(少し長い)ワンライナーを取得できます
ImmutableList<String> output =
ImmutableList.copyOf(Iterables.transform(input, function));
Iterables.transform
の結果が遅延しているため、これは一種の最適であり、一時リストは割り当てられません。 AFAIKにはいくつかの小さな非効率性があります。
FluentIterable
の割り当て速度を本当に気にするなら、それをベンチマークして、次のようなものと比較することができます
ArrayList<String> tmp = Lists.newArrayListWithCapacity(input.size());
Iterables.addAll(tmp, Iterables.transform(input, function));
ImmutableList<String> output = ImmutableList.copyOf(tmp);
そして手巻きループに。
最初のアプローチは確かに最も読みやすいアプローチですが、配列のサイズ変更と最終的なサイズへの縮小のためにいくつかの割り当てが発生します。長さ1234567のリストを使用すると、次のサイズ変更手順があります。
4-> 7-> 11-> 17-> 26-> 40-> 61-> 92-> 139-> 209-> 314-> 472-> 709-> 1064-> 1597-> 2396-> 3595- > 5393-> 8090-> 12136-> 18205-> 27308-> 40963-> 61445-> 92168-> 138253-> 207380-> 311071-> 466607-> 699911-> 1049867-> 1574801
そして最終的な縮小
1574801-> 1234567
ルイとクリスが言ったように、最適な解決策は
ImmutableList<String> output =
ImmutableList.copyOf(Lists.transform(input, function));
配列のコピーが含まれていないため。これは、Lists.transform
が遅延コレクションであり、ImmutableList.copyOf
が適切なサイズの配列を割り当てるためにそのサイズを照会した結果として機能します。 Iterables.transform
もFluentIterable
もそれほど効率的ではないことに注意してください。
あなたはすでにそのようなワンライナーのいくつかの例を書いていると思います。変換は、新しいオブジェクトの最小限の作成で行われます。実際、Guavaは怠惰な方法で機能します。リストを反復処理したり、他の要素を作成したり、別のリストに配置したりすることはありません。それは、その要素が必要とされる限り満たされる怠惰なリストを作成します。新しいリストを繰り返し処理している間。 Java 8クロージャを使用すると、同様のバイトコードが実行されますが、構文は短くなるため、このユースケースではそれほど高速ではないと思います。
input.stream().collect(toImmutableList())
が必要なものだと思います。 doc を参照してください