連載
» 2004年08月24日 10時00分 公開

JavaTips 〜Javaプログラミング編:配列とコレクション間の相互変換を行う

[BULL,@IT]

 複数要素で構成されるデータをJavaで扱う場合は、配列またはCollectionインターフェイスを持つクラスを使用するのが一般的です。Collectionインターフェイスを持つクラスには、java.util.ArrayListやjava.util.HashSetなどがあります。

 配列は要素数が固定となりますが、使用メモリが少ないという特徴があります。他方、Collectionインターフェイスを持つクラスは配列よりも使用メモリが多くなりますが、要素を自由に追加・削除できるという特徴があります。プログラムを記述する際は、それぞれの特徴を考えてどちらを使用するか決定することができます。

 しかし、ライブラリのメソッドに複数要素のデータを渡す場合、渡すべきデータを保持している型と、ライブラリのメソッドの引数の型が異なるため、型変換が必要になることがあります。本稿ではそうした場合に対応できるよう、配列とコレクション間で相互変換を行う方法を紹介します。

配列をコレクションに変換

 配列をコレクションに変換するには、java.util.Arraysクラスの静的メソッドであるasList(Object[])を使います。asList(Object[])メソッドの戻り値の型はListですが、Listはコレクションの派生インターフェイスを持つため、コレクションとして扱うことができます。

 以下は、Stringの配列をコレクションの1つであるListに変換するサンプルコードです。

Array2Collection.java
import java.util.Iterator;
import java.util.List;

public class Array2Collection {
    public static void main(String[] args) {
        String[] a = {"foo", "bar", "baz"};

        List l = java.util.Arrays.asList(a); //配列をコレクションの1つであるListに変換
        a[1] = "BAR"; // 配列中の1要素を変更
        for (Iterator i = l.iterator(); i.hasNext();) {
            System.out.println((String)i.next()); //変更がList側にも反映
        }
        System.out.println("----");

        l.set(0, "FOO"); // List中の1要素を変更
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]); //変更が配列側にも反映
        }
        
        try {
            l.add("zoo"); / /配列の要素数は固定なので例外発生
        } catch (UnsupportedOperationException e) {
            System.out.println("配列から変換したListの要素数は変更できません");
        }
    }
}


 このサンプルコードの実行結果は次のとおりです。

実行結果
foo
BAR
baz
----
FOO
BAR
baz
配列から変換したListの要素数は変更できません


 なお、asList(Object[])メソッドで取得したListオブジェクトは、変換元配列の「コピー」ではなく、変換元配列「そのもの」をあたかもListとして見せているものになります。そのため、変換元配列の要素を変更すると、それが変換後のListにも反映されます。また、逆に変換後のListの要素を変更すると、それが変換前の配列にも反映されます。配列は要素数の変更ができないため、変換後のListに対して、要素数の変更を行う動作(add、remove、clearメソッドの実行)を行うと、例外(java.lang.UnsupportedOperationException)が発生します。

コレクションを配列に変換

 コレクションを配列に変換するには、当該コレクションインスタンスの引数なしのtoArrayメソッドまたはtoArray(Object[])メソッドを使います。引数なしのtoArrayメソッドは、Object[]型の配列を返します。toArray(Object[])メソッドは、以下のように動作します。

  • 引数として与えられた配列に全要素が収まる場合は、引数として与えられた配列に全要素を収め、その配列を戻り値として返す
  • 引数として与えられた配列に全要素が収まらない場合は、引数として与えられた配列と同じ型の配列を新規に生成し、新規に生成された配列に全要素をセットして戻り値として返す
  • コレクションの要素の型が、引数として渡された配列の要素の型に代入できない場合は、例外(java.lang.ArrayStoreException)を発生する
  • toArray(Object[])メソッドの引数に要素が0個の配列をセットすると、引数にセットされた配列と同じ型で、当該Collectionの全要素がセットされた新規配列を返す

 前述した「配列をコレクションに変換」する場合とは異なり、toArrayメソッドやtoArray(Object[])メソッドを用いてコレクションから配列に変換する際は「コピー」が行われるため、変換元コレクションに変更を加えても変換先配列の内容は変換されません。また、その逆も同じです。

 以下は、コレクションの1つであるArrayListを、Stringの配列に変換するサンプルコードです。

Collection2Array.java
import java.util.ArrayList;
import java.util.Iterator;

public class Collection2Array {
    public static void main(String[] args) {
        ArrayList l = new ArrayList();
        l.add("foo");
        l.add("bar");
        l.add("baz");

        String[] a = (String[])l.toArray(new String[0]); //コレクションからStringの配列に変換

        l.set(1, "BAR"); //コレクションの内容を変更
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]); //コレクションの変更は配列には影響しない
        }
        System.out.println("----");
        
        a[0] = "FOO"; //配列の内容を変更
        for (Iterator i = l.iterator(); i.hasNext(); ) {
            System.out.println((String)i.next()); //配列の変更はコレクションに影響しない
        }

    }
}


 このサンプルコードの実行結果は次のとおりです。

実行結果
foo
bar
baz
----
foo
BAR
baz


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。