[Java How To Programming] [Home on 246net] [Home on Alles net]
Powered by SmartDoc

配列の使い方

2010/07/12 (月曜日) 23:55:36
TAKAHASHI, Toru
torutk@alles.or.jp

目次

配列の操作

配列の生成

配列を生成するには、newを使用します。配列の各要素は、その型のデフォルト値に初期化されます。double型の場合は0.0、参照型の場合はnullです。

配列の生成
// プリミティブ型を要素に持つ配列
double[] values = new double[8];
// 参照型を要素に持つ配列
ShipType[] myShips = new ShipType[12];

配列は、配列初期化子を与えて初期化することもできます。

配列初期化子を与えて初期化
double[] values = { 1.41421356, 1.7320508 };
String[] names = { "Thomas", "Edward", "Henry", "Gordon", "James", "Percy" \
    };

ShipType typeA = new ShipType(100);
ShipType typeB = new ShipType(300);
ShipType[] myShipType = { typeA, typeB };

// ネストした配列
int[][] params = { { 1 }, { 1, 2 }, { 3, 5, 8 }, { 13, 21, 34, 55 } };
Genericsな配列は生成できない

Genericsな型の配列は生成できません。

コンパイルエラー
Callable<String>[] tasks = new Callable<String>[12];

JavaVMは配列の要素格納時に要素の代入可能性を検査していますが、Genericsの場合実行時には型情報がなくなってしまうので、検査不可能となるため、これを許さないようになっています。

配列をコピーする

配列をコピーするには、cloneメソッド、Systemクラスのarraycopyメソッド、java.util.ArraysクラスのcopyOfメソッドがあります。

cloneによる配列のコピー

cloneによる配列のコピー
private ShipType[] shipTypes = ...
  :
public ShipType[] getShipTypes() {
    return (ShipType[])shipTypes.clone();
}

クラスの属性に保持している配列をアクセッサメソッドで利用側に返却する際に、本来クラス内部に隠蔽されるべき属性をそのまま渡してしまうことは非常に危険なプログラミングになるので、コピーを生成して返却します。

System.arraycopyによる配列のコピー

System.arraycopyによる配列のコピー
ShipType[] shipTypes = ...
ShipType[] types = new ShipType[shipTypes.length];
System.arraycopy(shipTypes, 0, types, 0, shipTypes.length);

Arrays.copyOfによる配列のコピー

Arrays.copyOfによる配列のコピー
ShipType[] types = Arrays.copyOf(shipTypes, shipTypes.length);

配列の結合

同じ型の配列が2つあった時に、これらを結合したいことがあります。

配列の結合
public ShipType[] concat(ShipType[] myShipTypes, ShipType[] enemyShipTypes) {
    int totalLength = myShipTypes.length + enemyShipTypes.length;
    ShipType[] allShipTypes = new ShipType[totalLength];
    System.arraycopy(myShipTypes, 0, allShipTypes, 0, myShipTypes.length);
    System.arraycopy(enemyShipTypes, 0, allShipTypes, myShipTypes.length,
                     enemyShipTypes.length);
    return allShipTypes;
}

配列のソート

java.util.Arraysクラスのsortを使います。

配列の比較

java.util.Arraysクラスのequalsメソッドを使いますが、多重配列の場合、各要素の配列のそれぞれの要素も比較する、deepEqualsメソッドを使います。deepEqualsメソッドに対応するハッシュコード取得メソッドdeepHashCodeもあります。

配列の中から検索

配列の内容を一定値で埋める

java.util.Arraysクラスのfillメソッドを使います。

配列の内容を印字する

Java 5.0 Tigerから導入

配列の印字
import java.util.Arrays;

public static void main(String[] args) {
    System.out.println(Arrays.toString(args));
}

これを実行すると、

[こんにちは, java, Tiger, さよなら]

のように印字されます。

多重配列の場合、Arrays.toString()メソッドでは、配列オブジェクトのtoString()が印字されてしまうので、Arrays.deepToString()メソッドを使用します。

配列の印字
    int[][] matrix = { {0,1,2}, {1,2,3}, {2,3,4} };
    System.out.println(Arrays.toString(matrix));
    System.out.println(Arrays.deepToString(matrix));
[[I@3e25a5, [I@19821f, [I@addbf1]
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]

16進ダンプ

バイナリの配列(byte[])を、16進数値およびそのASCIIコード文字でダンプする、いわゆるHEXダンプを簡単に実現する方法を見てみます。

ひとつは、JDKに非公式で搭載されている、sun.misc.HexDumpEncoderクラスを使用する方法です。非公式なのでいつAPIが変更されたり削除されたりするか保証はありませんが、とても簡便に使えます。StringオブジェクトやOutputStreamへ出力するメソッドが提供されています。

もうひとつは、Apache CommonsのI/Oに含まれるHexDumpクラスを使用する方法です。こちらはOutputStreamへの出力メソッドが提供されてますが、直接Stringオブジェクトへ出力するメソッドは提供されていません。

sun.misc.HexDumpEncoderの使用例

配列の印字(System.outへの出力)
import sun.misc.HexDumpEncoder;
    :

    HexDumpEncoder hexDump = new HexDumpEncoder();
    byte[] buffer = new byte[MAX_BUFFER_SIZE];
    int numRead = in.read(buffer);
    byte[] receivedBuffer = Arrays.copyOf(buffer, numRead);
    hexDump.encodeBuffer(receivedBuffer, System.out);

出力例は以下のとおりです。

HexDumpEncoderの出力例
0000: 48 65 6C 6C 6F 2C 20 52 53 2D 32 33 32 43 20 77 Hello, \
    RS-232C w
0010: 6F 72 6C 64 21                                  orld!

HexDumpEncoderのメソッドは、以下が提供されています。

sun.misc.HexDumpEncoderクラスのメソッド
戻り値型 メソッド名 引数 例外 備考
void encode ByteBuffer、OutputStream IOException
void encode InputStream、OutputStream IOException
void encode byte[]、OutputStream IOException 最後改行なし
void encodeBuffer InputStream、OutputStream IOException
void encodeBuffer byte[]、OutputStream IOException 最後改行あり
void encodeBuffer ByteBuffer、OutputStream IOException
String encodeBuffer byte[]
String encode ByteBuffer
String encode byte[] 最後改行なし
String encodeBuffer byte[] 最後改行あり
String encodeBuffer ByteBuffer、OutputStream IOException
String encodeBuffer ByteBuffer

Apache Commons IOのHexDump使用例

配列の印字(System.outへの出力)
import org.apache.commons.io.HexDump;
    :
    byte[] buffer = new byte[MAX_BUFFER_SIZE];
    int numRead = in.read(buffer);
    byte[] receivedBuffer = Arrays.copyOf(buffer, numRead);
    try {
        HexDump.dump(receivedBuffer, 0, System.out, 0);
    } catch (IOException e) {
        e.printStackTrace();
    }

出力例は以下のとおりです。

HexDumpEncoderの出力例
00000000 48 65 6C 6C 6F 2C 20 52 53 2D 32 33 32 43 20 77 Hello, \
    RS-232C w
00000010 6F 72 6C 64 21                                  orld!

参考