LoginSignup
52
45

えっ、まだList<T>使ってるの? [C#, コレクション]

Posted at

C#のコレクションの話です.
どうも特に理由なくList<T>を漠然と使うようなコードをまま見るので,コレクション型の使い分けについて書いていきます.

TL;DR

コレクション型には様々な種類があり,それそれに違った利点があるので,何でもList<T>を使うのではなく場面に合ったものを使おうね!

List<T>が適している場合

List<T>の一番の強みは,配列のようにインデックスでアクセスできることです.ご存知の通り,list[2]のような書き方でn番目の要素を取り出すことができます.この順番は勝手に変わったりしないので,順番に意味がある場合にも使えます.

var numList = new List<string>(){ "ぜろ", "いち", "に" };
var item = numList[2];  // "に"

また,要素の中からランダムに1つ選ぶような処理でもよく使われます.0-要素数の範囲で乱数を生成し,その乱数をインデックスとしてアイテムを取り出すことで,リストの中からランダムに1つの要素が得られます.

var random = new Random();
var item1 = numList[random.Next(numList.Count)];  // "に"
var item2 = numList[random.Next(numList.Count)];  // "ぜろ"
var item3 = numList[random.Next(numList.Count)];  // "に"
var item4 = numList[random.Next(numList.Count)];  // "いち"

逆に言えば,これらの用途ではない場合は他の型の使用を検討すべきです.

Stack<T>, Queue<T>

要素の追加順が大事なときに使うのがこの2つです.

Stack<T>は,その名の通り上に積み重ねるように要素を追加します.要素を取り出すときは一番上から取り出すので,最後に追加された要素が取り出されます.

Queue<T>は,要素を順番待ちの行列の一番後ろに追加します.要素を取り出すときは一番前のものを取り出すので,最初に追加された要素から順に取り出されます.

HashSet<T>

順番に意味がなく,要素が重複しない,もしくは重複しているかどうか調べたいときに使います.

HashSet<T>は,順番に意味を持ちません.そのため,[]を使ってインデックスでアクセスすることはできません.

また,HashSet<T>には同じ要素を複数追加することはできません.
Addメソッドで要素の追加を行いますが,すでに同じ要素が含まれており,追加できなかった場合はfalseが返ります.
この特性を利用して,例えば同じオブジェクトに対しては1回だけ処理を行うような処理を書くことができます.

// ChackUser済のUser
private readonly HashSet<User> checkedUsers = new();

public void CheckUser(User user)
{
    // CheckUserしたことがある場合,要素が重複するのでfalseが返る
    if (!checkedUsers.Add(user))
    {
        return;
    }
    // 以下メソッドの処理
}

まとめ

それぞれに書いたような目的は,極論List<T>でもLINQやループを使えば達成できますが,当然目的に合ったものを使った方が圧倒的に利点が多いです.
HashSetで例に挙げたような処理をListで行う場合,Containsで重複を確認して,重複していなかったらAddして,と非常にまどろっこしいことになります.

他の利点や計算量などの違いもありますが,状況によってコレクションを使い分けることでパフォーマンスの向上が期待できますし,コードも読みやすくなります.

コレクションに漠然とList<T>を使う前に,本当にそれが適切なのか,ぜひとも一度見直してみてほしいと思います.

参考

52
45
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
52
45