【Java】配列・リスト・マップの使い方についての基本

スポンサーリンク

Javaの配列・リスト(List)・マップ(Map)について基本的な事をまとめてみました。リストとマップについては色々種類もあるしそこら辺も書きたかったんですが、長くなりそうだったので別記事にしたいと思います。

なお、今回の内容はJava7 までのやり方になります。Java8 に関しては List と Map の繰り返しについてもforEach()とか他にも便利なメソッドが追加されてたりしますが、ラムダ式も一緒に書きたいのでこれも別記事でまとめます。

配列について

配列は同じデータ型の値を複数件扱う際に使用します。配列に格納する値は、基本データ型、参照型いずれの値も格納可能です。ただし、配列自体は参照型となります。

配列の生成

基本的な構文は以下の通りです。

データ型[] 配列名 = new データ型[要素数];
データ型 配列名[] = new データ型[要素数];

配列の宣言のデータ型と配列名に指定されている [ ] の位置はどちらでもかまいません(個人的にはデータ型に指定する方が好み)。実際にStringの配列を生成する場合は以下の通りです。

String[] array = new String[3];

私もそうでしたが、これを見た時Javaを勉強し始めて少し知識がついてきた人は、あれ?と思う箇所があるかもしれません。new で String 配列を生成した時に( )は必要ないのかという点です。通常であればnew String();と記述しますが、ここでは配列の領域を確保しているだけで、Stringオブジェクトの生成はされていないからです(言い方合ってるかな)。なので上記で生成したデータがどうなっているかというと[null, null, null, null, null]という状態です。

また、配列の宣言とともに初期化をする事もできます。例として String で書いてますが独自クラスなんかでも同じです。書き方としてはいくつかありますがこんな感じ。

String[] array = { new String(), new String(), new String() };
String[] array = new String[] { "apple", "orange", "grapes" };
String[] array = { "apple", "orange", "grapes" };

配列データへのアクセス

配列データへのアクセスは以下の通りです。

要素名[インデックス] = hoge;    // データを格納
hoge = 要素[インデックス];    // データを取得

データ格納・取得する場合はインデックスを指定しなければいけません。インデックスは「0」から始まります。例えば要素数を「3」で作成した場合、インデックスは「0」〜「2」です。特徴として作成時に指定した要素数を超えたデータは扱えないという決まりがあります。

public class ArrayTest {
    public static void main(String[] args) {
        String[] array = new String[3];
        array[0] = "apple";
        array[2] = "orange";
        array[3] = "Grapes";  // 配列数を超えている
    }
}

このように要素数を超えた位置にアクセスしようとした場合、例外が発生します。

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
    at data01.ArrayTest.main(ArrayTest.java:6)

配列の繰り返し処理

配列に対する繰り返し処理をする場合、配列の長さの取得にはarray.lengthを使用します。

String[] array = { "apple", "orange", "grapes" };
for(int i=0; i<array.length; i++) {
    System.out.println(array[i]);
}

拡張for文も当然可能です。

String[] array = { "apple", "orange", "grapes" };
for(String str : array) {
    System.out.println(str);
}

可変長引数

引数に配列を指定する場合、まず思いつくのがこの書き方。

public void method(String[] str) {
    ・・・
}

しかし、これだと配列を生成して渡してやらなければいけません。いちいちmethod(new String[] {・・・})とか書くのも煩わしいのでこちらの書き方に変更します。

public void method(String...str) {
    ・・・
}

こうすると配列を生成する必要なく、method(a, b, …);のようにString型の変数を渡したい数だけ渡せばよくなります。

おまけ

要素数 0 で生成した場合。

String[] array = new String[0];

formの初期化とかで使ったりしますが、要素数は 0 なので要素へ格納も取得もできません。新しく配列を作成しましょう。

array = new String[5];

リスト(List)について

リストはサイズ変更が可能な配列のようなものです。ただし、配列と違い格納できるデータは参照型のみになります。

リストの生成

基本的な構文は以下の通りです。

List<データ型> リスト名 = new ArrayList<データ型>(初期サイズ);

初期サイズは必須ではありません。もちろん最初に 10 と指定したからといって、それ以上データを追加出来ないわけでもないです。右側のデータ型に関しては省略可能です。データ型自体を省略する書き方も一応出来ますが、何でも格納できてしまうのでやらない方がいいでしょう。

List<データ型> リスト名 = new ArrayList<省略>();  // 右側のデータ型を省略
List リスト名 = new ArrayList();  // データ型を省略

また、ArrayList のインスタンスなのに変数が List で定義されているのを昔は疑問に思ってましたが、当然こっちの書き方もできます。

ArrayList<データ型> リスト名 = new ArrayList<データ型>(初期サイズ);

ここら辺に関しての説明は書かないですが調べたら理由は色々と出てくると思います。正直、個人的にはどっちでもいいんですが、 List で定義するのを統一した方が分かり易いかなと。

リストへのアクセス

インデックスは配列と同じく 0 から始まります。

  • データの追加:List.add(データ);
  • データの取得:List.get(インデックス);
  • データの削除:List.remove(インデックス);
  • データの更新:List.set(インデックス, データ);
  • リストの長さ:List.size();

リストの繰り返し処理

リストに対する繰り返し処理をする場合。

for(int i=0; i<list.size(); i++) {
    System.out.println(list[i]);
}

拡張for文も当然可能です。

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

マップ(Map)について

マップはキーと値が対になったデータ構造です。キーの重複は許可されていません。格納できるデータは参照型のみになります

マップの生成

基本的な構文は以下の通りです。

Map<データ型, データ型> マップ名 = new HashMap<データ型, データ型>(容量);

これもリストと同じく省略した書き方が可能です。

Map<データ型, データ型> マップ名 = new HashMap<省略>();  // 右側のデータ型を省略
Map マップ名 = new HashMap();  // データ型を省略

マップへのアクセス

  • マップに追加:Map.put(key, value);
  • マップの取得:Map.get(key);
  • マップの削除:Map.remove(key);
  • キーが有るか:Map.containsKey(key);
  • マップの長さ:Map.size();

マップの繰り返し処理

マップの繰り返しは配列・リストと少し違って以下のような形になります。

keyとvalueのセットを1件づつ取得

for(Map.Entry<Integer, String> hoge : map.entrySet()) {
    System.out.println(hoge.getKey() + " : " + hoge.getValue());
}

keyのみ1件づつ取得

for(Integer hoge : map.keySet()) {
    ・・・
}

valueのみ1件づつ取得

for(String hoge : map.values()) {
    ・・・
}

関連記事

 Java8のforEachを使った繰り返し処理について - TASK NOTES

 Java8ラムダ式の使い方の基本 - TASK NOTES

 Java8のStream APIの使い方(Streamの生成編)

 Java8のStream APIの使い方(中間操作編① - filter, map)

 Java8のStream APIの使い方(中間操作編② - flatMap, distinct, limit, skip)

 Java8のStream APIの使い方(中間操作編③ - sorted, peek)