JavaでコレクションをArrayListに変換する
1概要
Javaコレクションをあるタイプから別のタイプに変換することは、一般的なプログラミング作業です。このチュートリアルでは、あらゆる種類の
Collection
を
ArrayList
に変換します。
チュートリアルを通して、私たちは
Foo
オブジェクトのコレクションをすでに持っていると仮定します。そこから、さまざまな方法で____ArrayListを作成します。
** 2例を定義する
しかし続ける前に、入力と出力をモデル化しましょう。
私たちのソースはどんな種類のコレクションでもよいので、
Collection
インターフェースを使って宣言します。
Collection<Foo> srcCollection;
同じ要素型を持つ
ArrayList
を生成する必要があります。
ArrayList<Foo> newList;
3 ArrayListコンストラクタの使用
コレクションを新しいコレクションにコピーする最も簡単な方法は、そのコンストラクタを使用することです。
以前のhttps://www.baeldung.com/java-arraylist[guideList to ArrayList]で、
ArrayList
コンストラクタがコレクションパラメータを受け取ることができることを学びました。
ArrayList<Foo> newList = new ArrayList<>(srcCollection);
-
新しい
ArrayList
には、その中のFoo要素の浅いコピーが含まれます
ソースコレクション。
-
順番はソースコレクションの順番と同じです。
-
コンストラクターが単純なので、ほとんどのシナリオでそれは素晴らしい選択肢になります。
4 Streams APIを使用する
それでは、Streams APIを利用して、既存のCollectionからArrayListを作成しましょう。
ArrayList<Foo> newList = srcCollection.stream().collect(toCollection(ArrayList::new));
このスニペットでは:
-
ソースコレクションからストリームを取り出して、
collect()
演算子
Listを作成する
** 欲しいリストタイプを得るために
ArrayList :: new__を指定します
-
このコードでは、浅いコピーも作成されます。
正確な
List
型を気にしないのであれば、次のように単純化できます。
List<Foo> newList = srcCollection.stream().collect(toList());
toCollection()
と
toList()
は
Collectors
から静的にインポートされます。詳細については、https://www.baeldung.com/java-8-collector[Java 8のCollectorsガイド]を参照してください。
5ディープコピー
我々が「浅いコピー」に言及する前に。つまり、新しいリストの要素は、ソースコレクションにまだ存在しているものとまったく同じ
Foo
インスタンス** であるということです。したがって、
__Foo
sを参照によって
newList__にコピーしました。
どちらかのコレクションの
Foo
インスタンスの内容を変更すると、その変更は両方のコレクションに反映されます。したがって、どちらか一方のコレクション内の要素をもう一方を変更せずに変更する場合は、「ディープコピー」を実行する必要があります。
Foo
をディープコピーするために、各要素に対して** まったく新しい
Foo
インスタンスを作成します。したがって、すべての
Foo
フィールドを新しいインスタンスにコピーする必要があります。
自分自身をディープコピーする方法がわかるように
Foo
クラスを定義しましょう。
public class Foo {
private int id;
private String name;
private Foo parent;
public Foo(int id, String name, Foo parent) {
this.id = id;
this.name = name;
this.parent = parent;
}
public Foo deepCopy() {
return new Foo(
this.id, this.name, this.parent != null ? this.parent.deepCopy() : null);
}
}
ここで、フィールド
id
と
name
が
int
と
String
であることがわかります。これらのデータ型は値によってコピーされます。したがって、単純に両方を割り当てることができます。
parent
フィールドはクラスである別の
Foo
です。
__Foo
gotが変更された場合、その参照を共有するコードはすべてこれらの変更の影響を受けます。
parent__フィールドをディープコピーする必要があります 。
これで、
ArrayList
変換に戻ることができます。 ** ディープコピーをフローに挿入するには
map
演算子が必要です。
ArrayList<Foo> newList = srcCollection.stream()
.map(foo -> foo.deepCopy())
.collect(toCollection(ArrayList::new));
どちらにも影響を与えずに、どちらのコレクションの内容も変更できます。
ディープコピーは、要素数とデータの深さによっては時間がかかる場合があります。ここで並列ストリームを使用すると、必要に応じてパフォーマンスが向上する可能性があります。
6. リストの順序を制御する
デフォルトでは、ストリームは要素がソースコレクションで検出されたのと同じ順序で
ArrayList
に配信されます。
その順序を変更したい場合は、
sorted()
演算子をストリームに適用することができます。
Foo
オブジェクトを名前でソートするには
ArrayList<Foo> newList = srcCollection.stream()
.sorted(Comparator.comparing(Foo::getName))
.collect(toCollection(ArrayList::new));
私たちはこのhttps://www.baeldung.com/java-stream-ordering[earlierチュートリアル]でストリームの順序付けに関する詳細を見つけることができます。
7. 結論
ArrayList
コンストラクタは、
Collection
の内容を新しい
ArrayList
に取得するための効果的な方法です。
ただし、結果リストを微調整する必要がある場合は、Streams APIがプロセスを変更するための強力な方法を提供します。
この記事で使用されているコードは、その全体がhttps://github.com/eugenp/tutorials/tree/master/core-java-collections[GitHubについて]で参照できます。