Java コレクションフレームワーク - Listインタフェースの実装クラス

配列はサイズが固定されているため、拡張が必要な場合はコレクションフレームワークを使用するのが一般的である。

コレクションフレームワークの概要(java.utilパッケージ)

java.utilコレクションは 크게2つのカテゴリに分類される:

  • Collection:単一の要素(value)を格納
  • Map:キーと値のペア(key-value)を格納

Collectionはさらに細分化される:

  • List:順序付けられ、重複を許容する
  • Set:順序付けられず、重複を許容しない

Listインタフェース主要な実装クラス:

  • ArrayList:検索処理が高速
  • Vector:同期化を지원(ArrayListの旧版)
  • Stack:後入れ先出し(LIFO)構造
  • LinkedList:挿入・削除処理が高速

ArrayListの操作

package com.example.collections;

import java.util.ArrayList;
import java.util.List;

public class ArrayListSample {
    public static void main(String[] args) {
        // コンストラクタのバリエーション
        List<String> list1 = new ArrayList<>();  // 初期容量指定なし
        List<String> list2 = new ArrayList<>(10);  // 初期容量10
        List<String> list3 = new ArrayList<>(list2);  // 既存コレクションから生成
        List<Integer> list4 = new ArrayList<>();  // ジェネリック тип指定

        // 要素の追加
        list4.add(100);
        list4.add(200);
        list4.add(300);
        displayElements(list4);
        // 100 200 300

        list4.add(1, 150);  // インデックス1に挿入
        displayElements(list4);
        // 100 150 200 300

        // 要素の削除
        list4.remove(1);  // インデックス1の要素を削除
        displayElements(list4);
        // 100 200 300
        list4.remove(Integer.valueOf(200));  // 値を指定して削除

        // 要素の変更
        list4.set(0, 500);  // インデックス0の要素を置換
        displayElements(list4);
        // 500 300

        // 要素の取得
        System.out.println("インデックス1の要素: " + list4.get(1));
        // インデックス1の要素: 300

        // サイズの取得
        System.out.println("コレクションサイズ: " + list4.size());
        // コレクションサイズ: 2

        // 全要素の表示(toStringメソッドがオーバーライド済み)
        System.out.println(list4);
        // [500, 300]

        // 他のコレクション操作
        List<String> baseList = new ArrayList<>();
        baseList.add("X");
        baseList.add("Y");
        baseList.add("Z");

        List<String> targetList = new ArrayList<>();
        targetList.add("A");
        targetList.addAll(baseList);  // 全要素を追加
        System.out.println(targetList);
        // [A, X, Y, Z]

        targetList.retainAll(baseList);  // 共通要素のみ残す(交集)
        System.out.println(targetList);
        // [X, Y, Z]

        targetList.clear();  // 全要素を削除
        System.out.println(targetList.isEmpty());
        // true

        // 要素の存在確認
        List<String> searchList = new ArrayList<>();
        searchList.add("P");
        searchList.add("Q");
        searchList.add("P");
        searchList.add("R");

        System.out.println("Pが含まれるか: " + searchList.contains("P"));
        // Pが含まれるか: true
        System.out.println("最初のPのインデックス: " + searchList.indexOf("P"));
        // 最初のPのインデックス: 0
        System.out.println("最後のPのインデックス: " + searchList.lastIndexOf("P"));
        // 最後のPのインデックス: 2

        // 配列への変換
        String[] stringArray = searchList.toArray(new String[0]);
        for (String item : stringArray) {
            System.out.print(item + " ");
        }
        System.out.println();
        // P Q P R
    }

    private static void displayElements(List<Integer> list) {
        for (Integer num : list) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

VectorとStackの特徴

Vectorは旧型のコレクションクラスであり、スレッドセーフ(同期化)が保証される。シングルスレッド環境ではArrayListの方が高速である。

Vectorのデフォルト拡張率は2倍。ArrayListは1.5倍(capacity + (capacity >> 1))である。

Stackクラス(後入れ先出し):

package com.example.collections;

import java.util.Stack;

public class StackSample {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();

        // 要素をスタックに押し込む
        stack.push("First");
        stack.push("Second");
        stack.push("Third");

        System.out.println("pop実行: " + stack.pop());  // トップ要素を取り出す
        // pop実行: Third

        System.out.println("peek実行: " + stack.peek());  // トップ要素を Peak(削除しない)
        // peek実行: Second

        System.out.println("現在のスタック: " + stack);
        // 現在のスタック: [First, Second]

        System.out.println("'First'の位置: " + stack.search("First"));  // 栈頂から数えた位置
        // 'First'の位置: 2
    }
}

LinkedListとQueue(先入れ先出し)

LinkedListはQueueインタフェースも実装しており、両方の特性を持つ。

package com.example.collections;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;

public class LinkedListSample {
    public static void main(String[] args) {
        // Queueとしての使用(先入れ先出し)
        Queue<String> queue = new LinkedList<>();
        queue.offer("Item1");
        queue.offer("Item2");
        queue.offer("Item3");

        System.out.println("poll: " + queue.poll());  // 要素を取り出して削除
        // poll: Item1
        System.out.println("peek: " + queue.peek());  // 先頭を確認(削除しない)
        // peek: Item2

        // LinkedListのメソッド利用
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("A");
        linkedList.add("B");
        linkedList.add("C");

        linkedList.addFirst("Start");  // 先頭に挿入
        linkedList.addLast("End");     // 末尾に追加
        System.out.println(linkedList);
        // [Start, A, B, C, End]

        // Stackからの変換
        Stack<String> stack = new Stack<>();
        stack.push("X");
        stack.push("Y");
        stack.push("Z");

        LinkedList<String> fromStack = new LinkedList<>(stack);
        System.out.println(fromStack);
        // [X, Y, Z]

        // 要素の移除(先入れ先출력なので先頭から)
        System.out.println("remove: " + linkedList.remove());
        // remove: Start
        System.out.println(linkedList);
        // [A, B, C, End]

        // 性能比較:100,000件の要素を先頭に挿入
        LinkedList<String> linked = new LinkedList<>();
        ArrayList<String> array = new ArrayList<>();

        long startTime1 = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            linked.add(0, "Data");
        }
        long endTime1 = System.currentTimeMillis();

        long startTime2 = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            array.add(0, "Data");
        }
        long endTime2 = System.currentTimeMillis();

        System.out.println("LinkedList所要時間: " + (endTime1 - startTime1) + "ms");
        System.out.println("ArrayList所要時間: " + (endTime2 - startTime2) + "ms");

        // LinkedListは先頭への挿入が高速
        // ArrayListは末尾への挿入場合は高速
    }
}

タグ: Java arraylist LinkedList stack Vector

5月29日 22:43 投稿