Javaのコレクションと配列


Javaの配列やコレクションは集合を取り扱うデータ構造です。複数の要素(オブジェクト)の集合をうまく取り扱うことで、プログラムの見通しを改善できます。

🎂 コレクション

コレクション・フレームワークのインターフェースと具象クラスの一覧です。


出典:改訂2版 パーフェクトJava

コレクションを使うコードのサンプルです。ListはStringを要素とするリストです。
コレクション型の要素には参照型を指定します。インターフェースのListを使うのは、実装ArrayListよりも依存を下げるためです。

public class SampleList {
public static void main(String[] args) {
List list = new ArrayList<>(); // コレクションオブジェクトの生成
list.add("one"); // 要素オブジェクトを追加
list.add("two");
list.add("three");

for(String s : list) {
System.out.println(s);
}
}
}

🚌 Listインターフェースのメソッド

Listインターフェースの代表的なメソッドの紹介です。

メソッド名 説明
add 要素の追加
addAll 要素をまとめて追加
contains 要素の存在チェック
get 要素の取得
indexOf 要素の検索
lastIndexOf 後方からの要素の検索
remove 要素の削除(複数ある場合は最初の要素を削除)
set 要素の置換
size 要素数の取得
subList 部分リストの取得(コピーではなく、参照による部分リストを返す)


出典:改訂2版 パーフェクトJava

Listどうしの結合:addAll

JavaのListインターフェイスで定義されたaddAll()メソッドはListどうしを結合できます。

import java.util.ArrayList;
public class AddAllSample {
public static void main(String [] args) {
ArrayList list1 = new ArrayList();
list1.add("1-1");
list1.add("1-2");

ArrayList list2 = new ArrayList();
list2.add("2-1");
list2.add("2-2");

// list1 に list2 を結合
list1.addAll(list2);
list1.forEach(System.out::println);
}
}

結果は次のとおりで、2つのListが結合されているのがわかります。

1-1
1-2
2-1
2-2

🐯 ArrayListとLinkedListの選び方

Listインターフェースの主要な具象クラスは、配列を使った実装のArrayListとリンクノードを使った実装のLinkedListがあります。

  • ArrayListは取得(get)や要素の更新(set)が早いですが、要素の挿入(add)が早くありません
  • LinkedListは要素の挿入(add)、削除(remove)が早いですが、検索(indexOf)や要素の取得(get)は早くありません

上の特徴を踏まえて、ArrayListLinkedListは次のように使い分けます。

  • 要素の読み込み(検索)や書き換えが中心ならArrayListがよい
  • 要素の挿入や削除の頻度が高い場合はLinkedListが効率的

🚕 補足:ArrayのtoStringについて

配列ArraytoStringは次のような定義になります。

public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

つまり、配列をSystem.out.printlnに渡すとハッシュ値を返します。

🐮 補足:配列の初期化演算子

配列の初期化はいくつかパターンがあるので注意してください。

int[] array = { 2, 3 };
int[] array = new int[]{ 2, 3 };
int[][] array = new { { 2, 3 }, { 4, 5 } };

// 必要な次元数を自動で算出するのでOK
int[][] array = {};

以下はコンパイルエラーになるので注意してください。

// { xxx } で要素数を自動で取得するので指定してはだめ
int[] array = new int[2] { 2, 3 };

// 次元数が違うのでNG
int[][] array = new int[] {};

// 次元数の決定は初期化時に行うためNG
int e[];
e = { 2, 3 }

😼 補足:配列のコピー:arraycopy

配列のコピーを行うSystem.arraycopyは5つの引数を受け取る少し不雑なメソッドです。

引数 説明
第1引数 コピー元となる配列
第2引数 コピー元のどの位置からコピーを開始するか(0始まり)
第3引数 コピー先の配列
第4引数 コピー先配列のどの位置からコピーを開始するか(0始まり)
第5引数 第2引数のいちからいくつの要素をコピーするか
char[] arrayA = { 'a', 'b', 'c', 'd', 'e' };
char[] arrayB = new char[arrayA.length];
System.arraycopy(arrayA, 1, arrayB, 0, 4); //=> bcde

🎃 補足:java.util.Queueインターフェース

キュー専用のインターフェイス。Queueの実装はArrayDequeを使うと良さそう。

Queue queues = new ArrayDeque<>();
オプション 失敗時に例外 戻り値で判定
末尾に追加 add() offer()
先頭から削除 remove() poll()
先頭から取得(削除しない) element() peek()

🍮 補足:ArrayからArrayListへの変換

JavaでArrayからArrayListに変換する方法です。

String[] alpha = { "a", "b", "c", "d", "e" };
List list = Arrays.asList(alpha);

🎉 参考リンク

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍