回答:
x
コレクションはどこにありますか:
Foo[] foos = x.toArray(new Foo[x.size()]);
x.toArray(new Foo[0])
--- ドキュメンテーション:読む時間はありません...
(new Foo[0])
。Collection.toArrayのドキュメントのとおり、 `@param aこのコレクションの要素が格納される配列(十分な大きさの場合)。つまり、新しい配列に直接格納されます。サイズ0の配列を指定すると、新しい配列が作成されます。つまり、不要な場合は、小さな配列と大きな配列が作成されます。
toArray
正しい型のターゲット配列を作成するためのヒントにすぎません。そして、この場合、正直に言って、アプリケーションに1つの空の配列が1つ余分にあるかどうかは気にしません。それはノイズレベルをはるかに下回っています。
new Foo[0]
がシンプルであるが「最善ではない(メモリ)」と書いた理由です...つまり、私のソリューションは簡単ではあるが最善ではないということです(それが私が使用した理由です:
)。
new Foo[0]
カルロスによって提案されたバリアントは、この問題は生じません。
Java 8を使用して更新された質問の代替ソリューション:
Bar[] result = foos.stream()
.map(x -> new Bar(x))
.toArray(size -> new Bar[size]);
Bar[] result = foos.stream().map(Bar::new).toArray(Bar[]::new);
複数回またはループで使用する場合は、定数を定義できます
public static final Foo[] FOO = new Foo[]{};
そしてそれを好きなように変換します
Foo[] foos = fooCollection.toArray(FOO);
このtoArray
メソッドは空の配列を取得して、ターゲット配列の正しいタイプを判別し、新しい配列を作成します。
これが私のアップデートの提案です:
Collection<Foo> foos = new ArrayList<Foo>();
Collection<Bar> temp = new ArrayList<Bar>();
for (Foo foo:foos)
temp.add(new Bar(foo));
Bar[] bars = temp.toArray(new Bar[]{});
const
Java ではありません!public static final Foo[] FOO = {}
import static
てそれらを取得することもできます。
JDK / 11では、a Collection<Foo>
をan に変換する別の方法として、次のFoo[]
ものを利用できますCollection.toArray(IntFunction<T[]> generator)
。
Foo[] foos = fooCollection.toArray(new Foo[0]); // before JDK 11
Foo[] updatedFoos = fooCollection.toArray(Foo[]::new); // after JDK 11
@Stuartがメーリングリストで説明しているように(私の強調)、これのパフォーマンスは基本的に既存のものと同じであるはずですCollection.toArray(new T[0])
-
結論としては、
Arrays.copyOf(
)を使用する実装が最も速いということです。おそらくそれが組み込みであるためです。配列全体が上書きされることがわかっているため、新しく割り当てられた配列がゼロで埋められるのを回避できます。これは、パブリックAPIの外観に関係なく当てはまります。
JDK内のAPIの実装は次のとおりです。
default <T> T[] toArray(IntFunction<T[]> generator) {
return toArray(generator.apply(0));
}
デフォルトの実装では
generator.apply(0)
、長さ0の配列を取得するために呼び出し、次に単にを呼び出しますtoArray(T[])
。これはArrays.copyOf()
高速パスを経由するため、本質的にと同じ速度toArray(new T[0])
です。
注:-値のあるコードに使用する場合、APIの使用は後方非互換性に沿って誘導されるだけnull
です。たとえばtoArray(null)
、これらの呼び出しは既存のためにあいまいになりtoArray(T[] a)
、コンパイルに失敗するためです。
プロジェクトでGuavaを使用する場合は、を使用できますIterables::toArray
。
Foo[] foos = Iterables.toArray(x, Foo.class);
更新セクションのケースの最終的な解決策は次のとおりです(Googleコレクションの助けを借りています):
Collections2.transform (fooCollection, new Function<Foo, Bar>() {
public Bar apply (Foo foo) {
return new Bar (foo);
}
}).toArray (new Bar[fooCollection.size()]);
しかし、ここでの重要なアプローチは、doublepの回答で言及されていました(toArray
メソッドを忘れていました)。
new Bar[0]
問題を回避します。
たとえば、Studentクラスの要素を持つコレクションArrayListがあるとします。
List stuList = new ArrayList();
Student s1 = new Student("Raju");
Student s2 = new Student("Harish");
stuList.add(s1);
stuList.add(s2);
//now you can convert this collection stuList to Array like this
Object[] stuArr = stuList.toArray(); // <----- toArray() function will convert collection to array
Stream.toArray
はJDKの既存のAPIと一致します。