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について]で参照できます。