1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Java】コレクションフレームワーク

Posted at

コレクションとは

  • オブジェクトの集合
  • java.utulパッケージ:コレクション構造を扱うための汎用クラス/インターフェース(コレクションフレームワーク)を提供
  • オブジェクトの集合を扱う際にまず利用したい

Collectionインターフェース

  • コレクションフレームワークの基本
  • 各サブインターフェースの実装クラス
    • List:順序を持つ、要素は重複可能
      • ArrayList:可変長配列
      • LinkedList:リンク構造のリスト
    • Set:要素の重複不可
      • HashSet:任意順で格納された要素集合
      • LinkedHashSet:追加順で格納された要素集合
      • TreeSet:キーで並び替えられる要素集合
    • Queue:先頭/末尾要素の追加、削除。待ち行列/スタックに使う
      • ArrayDeque:両端キュー
      • LinkedList:LinkedListと同じ
    • Map:キー/値で管理、キーの重複不可
      • HashMap:基本Map
      • TreeMap:キーで並び替えられるMap

コレクションのインスタンス化

  • List<String> data = new ArrayList<>();

インターフェース型

  • 変数の型(実装型)ではなくインターフェース型を用いることでクラスへの依存を最小限にできる
  • NG例:実数型をそのまま引数で渡すのは良くない
    ArrayList<String> data = new ArrayList<>();
    public void run(ArrayList<String> data){…}
  • 最初からインターフェース型でList<String>としておけばLinkedListへの変更も容易!
  • List<String> data = new LinkedList<>();

ジェネリクス構文

  • 汎用的クラス/メソッドを特定の型に結びつける仕組み
  • List<String>の場合、汎用型(List)に対してStringを割り当て、文字列格納専用のListになる!
  • 逆に非ジェネリクスなコレクションでは全要素をオブジェクト型(全部の型を代入できる)とみなし、明示的型キャストが必要になるし、意図しない型の値を検出できない。。
    Strng str = (String)data.get(0)
  • 型安全なジェネリクス構文を使おう!
  • 左辺の要素型が明白な時は省略可能(ダイアモンド演算子)
    List<String> data = new ArrayList< >();

イディオム

インスタンス化のタイミングでまとめてコレクション初期化

import java.util.ArrayList;
public class Main {
  public static void main(String[] args) {
    //匿名クラス
    var data = new ArrayList<String>() {
      //初期化ブロック
      {
        add("neko");
        add("inu");
        add("tori");
      }
    };
    System.out.println(data);//[neko, inu, tori]
  }
}

拡張forでコレクション配下を順に処理

* 内部では**Iterator**を使用したwhile命令のシンタックスシュガー(簡単化した構文)
* Iteratorインターフェースのメソッド
    * **hasNext**:次の要素存在確認
    * **next**:次の要素に移動&取得
    * **remove**:現在要素削除
import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    var data = new ArrayList<String>() {
      {
        add("neko");
        add("inu");
        add("kuma");
      }
    };
    //コレクション配下を順に処理
    for (var s : data) {
      System.out.println(s); //neko inu kuma
    }
    // イテレーターを使った場合
    //     var itr = data.iterator();
    //     while (itr.hasNext()) {
    //      System.out.println(itr.next());
    //     }
  }
}

ループで要素削除

  • 拡張forではConcurrentModificationExceptionになるので注意
import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    var data = new ArrayList<String>() {
      {
        add("neko");
        add("inu");
        add("niwatori");
      }
    };

    var ite = data.iterator();
    while (ite.hasNext()) {
      System.out.println(ite.next()); //neko inu niwatori
      ite.remove();
    }
    System.out.println(data); //[]
  }
}
//NG例:拡張for
    for (var s : data) {
      System.out.println(s);
      data.remove(s);
    }

リストを逆順で読む

  • listIteratorメソッドでListIteratorオブジェクト取得
  • previousメソッド:前の要素に移動
  • hasPreviousメソッド:前の要素存在確認
  • listIterator引数に読み込み開始位置を指定
import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    var data = new ArrayList<String>() {
      {
        add("neko");
        add("inu");
        add("shimaenaga");
      }
    };
    //末尾を開始位置に設定
    var ite = data.listIterator(data.size());
    while (ite.hasPrevious()) {
      System.out.println(ite.previous()); //shimaenaga inu neko
    }
  }
}

配列とコレクションの変換

  • 基本はオブジェクトの集合は配列よりコレクション(オブジェクト指向構文との親和性)

配列からリストへ

  • asListメソッド
    • 変換したリストはあくまでもリストの皮を被った配列!
    • リストの変更は元の配列に影響、リストへの追加、削除はできない
    • Collections.addAllメソッドで複製
//NG例:既存文字列をリストに変換、変換後のリストに値を追加削除
import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    var data = new String[] { "cat", "dog", "bird"};
    var list = Arrays.asList(data);
    list.set(0, "neko");
    System.out.println(list); //[neko, dog, bird]
    System.out.println(Arrays.toString(data)); //[neko, dog, bird]
    //list.add("inu"); //UnsupportedOperationException
    //list.remove(0);  //UnsupportedOperationException
  }
}
//OK例:既存文字列をリストに変換、変換後のリストに値を追加削除
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class Main {
  public static void main(String[] args) {
    var data = new String[] { "cat", "dog", "bird" };
    var list = new ArrayList<String>();
    Collections.addAll(list, data);
    list.set(0, "neko");
    list.add("inu");
    System.out.println(list); //[neko, dog, bird, inu]
    list.remove(1);

    System.out.println(list); //[neko, bird, inu]
    System.out.println(Arrays.toString(data)); //[cat, dog, bird]
  }
}

コレクションから配列へ

  • toArrayメソッド
    • 引数の配列に全要素が収まるならその要素を設定
    • 収まらないなら引数と同じ方の配列を生成してから全要素設定
    • コレクション要素を配列要素型に変換できない場合ArrayStoreException
    • あくまで要素をコピーしているので変換元リストへの操作は配列に影響しない
import java.util.ArrayList;
import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    var data = new ArrayList<String>(Arrays.asList("cat", "dog", "bird"));
    //リストと同じサイズの配列strsに中身コピー
    var strs = new String[data.size()];
    data.toArray(strs);
    //変換元リストのみデータ追加
    data.set(0, "neko");
    System.out.println(Arrays.toString(strs)); //[cat, dog, bird]
    //変換元リストのみ変わってる
    System.out.println(data); //[neko, dog, bird]
  }
}

変更不可コレクションへの変換

  • unmodifiableメソッド
    • 変更しようとするとUnsupportedOperationException
    • 要素が参照型の場合、内容変更を制限できないことも(StringBuilderなど)
    • ofメソッドでも変更不能コレクション直接生成できる(Java9以降)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class Main {
  public static void main(String[] args) {
    var data = new ArrayList<String>(Arrays.asList("cat", "dog", "bird"));
    //変更不能なlistを生成
    var udata = Collections.unmodifiableList(data);
    udata.set(0, "neko"); //UnsupportedOperationException
    udata.add("inu");  //UnsupportedOperationException
  }
}
//StringBuilderではコレクション要素内容変更可能
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class Main {
  public static void main(String[] args) {
    var data = new ArrayList<StringBuilder>(Arrays.asList(
        new StringBuilder("もしもし"),
        new StringBuilder("かめさん"),
        new StringBuilder("よ")));
    var udata = Collections.unmodifiableList(data);
    udata.get(0).append("かめよ");
    System.out.println(udata); //[もしもしかめよ, かめさん, よ]
  }
}
//ofメソッドで変更不能コレクション直接生成
import java.util.List;
public class Main {
  public static void main(String[] args) {
    var data = List.of("cat", "dog", "bird");
    System.out.println(data);
    data.set(0, "neko"); //UnsupportedOperationException
  }
}

空コレクション生成

  • 戻り値がコレクションのメソッドでは、戻り値が空の場合nullではなくからコレクションを返す
  • emptyList / emptySet / emptyMapメソッド
  • return Collections.emptyList();

同期化コレクション生成

  • 同期化コレクション:マルチスレッド対応(=排他処理)するためのメソッド
    • synchronizedCollection / synchronizedList / synchronizedSet / synchronizedMapメソッド
  • マルチスレッド環境で安全に利用できる (=スレッドセーフ
  • var data = Collections.synchronizedList(new ArrayList<String>());
  • より性能のいい並列コレクション生成
    • CopyOnWriteArrayList / CopyOnWriteArraySet / ConcurrentHashMap
  • var map = new ConcurrentHashMap<String,String>();
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?