配列を生成するには、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な型の配列は生成できません。
Callable<String>[] tasks = new Callable<String>[12];
JavaVMは配列の要素格納時に要素の代入可能性を検査していますが、Genericsの場合実行時には型情報がなくなってしまうので、検査不可能となるため、これを許さないようになっています。
配列をコピーするには、cloneメソッド、Systemクラスのarraycopyメソッド、java.util.ArraysクラスのcopyOfメソッドがあります。
private ShipType[] shipTypes = ... : public ShipType[] getShipTypes() { return (ShipType[])shipTypes.clone(); }
クラスの属性に保持している配列をアクセッサメソッドで利用側に返却する際に、本来クラス内部に隠蔽されるべき属性をそのまま渡してしまうことは非常に危険なプログラミングになるので、コピーを生成して返却します。
ShipType[] shipTypes = ...
ShipType[] types = new ShipType[shipTypes.length];
System.arraycopy(shipTypes, 0, types, 0, shipTypes.length);
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]]
バイナリの配列(byte[])を、16進数値およびそのASCIIコード文字でダンプする、いわゆるHEXダンプを簡単に実現する方法を見てみます。
ひとつは、JDKに非公式で搭載されている、sun.misc.HexDumpEncoderクラスを使用する方法です。非公式なのでいつAPIが変更されたり削除されたりするか保証はありませんが、とても簡便に使えます。StringオブジェクトやOutputStreamへ出力するメソッドが提供されています。
もうひとつは、Apache CommonsのI/Oに含まれるHexDumpクラスを使用する方法です。こちらはOutputStreamへの出力メソッドが提供されてますが、直接Stringオブジェクトへ出力するメソッドは提供されていません。
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);
出力例は以下のとおりです。
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のメソッドは、以下が提供されています。
戻り値型 | メソッド名 | 引数 | 例外 | 備考 |
---|---|---|---|---|
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 |
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(); }
出力例は以下のとおりです。
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!
IBM:developerWorksの記事。配列の扱いについて詳しく解説された良資料。
「Java SE 6完全攻略」第35回 java.langパッケージの変更点
配列のコピーについて、java.util.ArraysのcopyOfメソッドの紹介がある。