2012-07-13T23:17:46の更新内容

programming/netfx/collections/2_generic_1_list/index.wiki.txt

current previous
16,20 16,7
 
#googleadunit(banner)
#googleadunit(banner)
 

        

        
 
*List [#List]
*List [#List]
~
&msdn(netfx,type,System.Collections.Generic.List`1){System.Collections.Generic.Listクラス};は[[配列>programming/netfx/arrays]]に非常によく似た機能を持つクラスですが、格納できる要素の数が固定である配列とは異なり''動的に要素の数を増減できる''という特徴を持っています。
&msdn(netfx,type,System.Collections.Generic.List`1){System.Collections.Generic.Listクラス};は[[System.Collections.ArrayList>programming/netfx/collections/1_nongeneric_1_arraylist#ArrayList]]に相当するジェネリックコレクションです。 基本的な操作は、ArrayListと同じです。
+

          
+
Listクラスは[[System.Collections.ArrayList>programming/netfx/collections/1_nongeneric_1_arraylist#ArrayList]]に相当するジェネリックコレクションですが、ただ単にジェネリックなArrayListというわけではなく、ArrayListと比べるとより高度な操作が可能になっています。
+

          
+

          
+
*基本操作
+
早速、Listクラスを使った基本的な操作について見ていきます。
+

          
+
**Listの作成・要素の取得・設定・列挙
+
Listを使う場合には、最初に格納する要素を指定することも、空のListを作成しておいて後から要素を追加することも出来ます。 追加する方法については後述するとして、以下の例ではあらかじめ要素が格納されているListを使うことにします。
+

          
+
List内の要素を取得(参照)するには、配列と同様にインデックスを指定します。 取得だけでなく、インデックスを指定することで特定の要素を設定(値の上書き)をすることも出来ます。 (C#ではインデクサによって、VB.NETでは既定のプロパティItemによって、配列と同様のインデックスによる取得・設定ができるようになっています。)
+

          
+
List内の全ての要素を列挙するには、配列同様にfor/foreach文を使うことが出来ます。 なお、現在List内に含まれている要素の数を取得するにはLengthプロパティではなく&msdn(netfx,member,System.Collections.Generic.List`1.Count){Countプロパティ};を参照します。
 

        

        
 
#tabpage(C#)
#tabpage(C#)
 
#code(cs){{
#code(cs){{
40,264 27,48
 
{
{
 
  static void Main()
  static void Main()
 
  {
  {
~
    // 初期状態で5つの要素があるstring型のListを作成
    List<int> list = new List<int>();
+
    List<string> list = new List<string>() {"Alice", "Bob", "Charlie", "Dave", "Eve"};
 

        

        
~
    // 要素の数を取得
    // 要素の追加
~
    Console.WriteLine("Count = {0}", list.Count);
    list.Add(0);
-
    list.Add(1);
-
    list.Add(2);
 

        

        
~
    // 要素を参照して表示
    Print(list);
+
    Console.WriteLine("list[0] -> {0}", list[0]);
+
    Console.WriteLine("list[3] -> {0}", list[3]);
+
    Console.WriteLine();
+

          
+
    // for文でList内の要素を列挙して表示
+
    for (int i = 0; i < list.Count; i++)
+
    {
+
      Console.WriteLine("list[{0}] = {1}", i, list[i]);
+
    }
+

          
+
    // foreach文でList内の要素を列挙して表示
+
    foreach (string e in list)
+
    {
+
      Console.WriteLine(e);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 初期状態で5つの要素があるstring型のListを作成
+
    Dim list As New List(Of String)(New String() {"Alice", "Bob", "Charlie", "Dave", "Eve"})
+

          
+
    ' 要素の数を取得
+
    Console.WriteLine("Count = {0}", list.Count)
+

          
+
    ' 要素を参照して表示
+
    Console.WriteLine("list(0) -> {0}", list(0))
+
    Console.WriteLine("list(3) -> {0}", list(3))
+
    Console.WriteLine()
+

          
+
    ' ForステートメントでList内の要素を列挙して表示
+
    For i As Integer = 0 To list.Count - 1
+
      Console.WriteLine("list({0}) = {1}", i, list(i))
+
    Next
+

          
+
    ' For EachステートメントでList内の要素を列挙して表示
+
    For Each e As String In list
+
      Console.WriteLine(e)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Count = 5
+
list[0] -> Alice
+
list[3] -> Dave
+

          
+
list[0] = Alice
+
list[1] = Bob
+
list[2] = Charlie
+
list[3] = Dave
+
list[4] = Eve
+
Alice
+
Bob
+
Charlie
+
Dave
+
Eve
+
}}
 

        

        
~
Listは要素の数は可変ですが、現在の要素数を超えるインデックスを指定した場合は例外ArgumentOutOfRangeExceptionがスローされます。 大きなインデックスを指定してもその分の領域が自動的に確保されるわけではない点に注意してください。
    // 複数の要素の追加
~

          
    list.AddRange(new int[] {3, 4, 5, 6});
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    List<int> list = new List<int>() {0, 1, 2};
+

          
+
    // インデックス0の要素に値を設定する
+
    // (インデックスは全要素数の範囲内なので例外はスローされない)
+
    list[0] = 3;
+

          
+
    // インデックス100の要素に値を設定する
+
    // (インデックスは全要素数の範囲を超えるため例外がスローされる)
+
    list[100] = 1000000;
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New List(Of Integer)(New Integer() {0, 1, 2})
+

          
+
    ' インデックス0の要素に値を設定する
+
    ' (インデックスは全要素数の範囲内なので例外はスローされない)
+
    list(0) = 3
+

          
+
    ' インデックス100の要素に値を設定する
+
    ' (インデックスは全要素数の範囲を超えるため例外がスローされる)
+
    list(100) = 1000000
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
ハンドルされていない例外: System.ArgumentOutOfRangeException: インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
+
パラメーター名: index
+
   場所 System.Collections.Generic.List`1.set_Item(Int32 index, T value)
+
   場所 Sample.Main()
+
}}
+

          
+
**要素の追加・挿入
+
Listは格納できる要素の数は可変であるため、任意の時点で要素を追加することが出来ます。 要素を追加するには、&msdn(netfx,member,System.Collections.Generic.List`1.Add){Addメソッド};を使います。 このメソッドを使うと、Listの一番最後に値が追加されます。 位置を指定して要素を挿入したい場合は&msdn(netfx,member,System.Collections.Generic.List`1.Insert){Insertメソッド};を使います。
+

          
+
複数の要素を一度にまとめて追加したい場合は、&msdn(netfx,member,System.Collections.Generic.List`1.AddRange){AddRangeメソッド};を使います。 他の配列やListの内容をコピーするにはfor/foreach文を使って要素を一つずつコピーすることもできますが、このメソッドを使うとfor/foreach文を使わなくても1度の呼び出しでまるごと追加することが出来ます。 なお、このメソッドではAddメソッド同様Listの末尾に要素が追加されます。 挿入する位置を指定したい場合には&msdn(netfx,member,System.Collections.Generic.List`1.InsertRange){InsertRangeメソッド};を使うことが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // 要素が格納されていない空のListを作成
+
    List<string> list = new List<string>();
+

          
+
    // 要素を追加する
+
    list.Add("Alice");
+
    list.Add("Charlie");
 

        

        
 
    Print(list);
    Print(list);
 

        

        
~
    // インデックス1の位置に要素を挿入する
    // 要素の削除
~
    list.Insert(1, "Bob");
    list.Remove(3);
-
    list.Remove(6);
 

        

        
 
    Print(list);
    Print(list);
 

        

        
~
    // 追加したい要素を含む配列
    // 特定の位置にある要素を削除
~
    string[] arr = new string[] {"Dave", "Eve", "Frank"};
    list.RemoveAt(0);
+

          
+
    // 複数の要素を追加する (配列に含まれている内容をすべて追加する)
+
    list.AddRange(arr);
 

        

        
 
    Print(list);
    Print(list);
+
  }
 

        

        
~
  static void Print(List<string> list)
    // 特定の位置にある要素を変更
~
  {
    list[2] = 7;
+
    foreach (string e in list)
+
    {
+
      Console.Write("{0}, ", e);
+
    }
+

          
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 要素が格納されていない空のListを作成
+
    Dim list As New List(Of String)()
+

          
+
    ' 要素を追加する
+
    list.Add("Alice")
+
    list.Add("Charlie")
+

          
+
    Print(list)
+

          
+
    ' インデックス1の位置に要素を挿入する
+
    list.Insert(1, "Bob")
+

          
+
    Print(list)
+

          
+
    ' 追加したい要素を含む配列
+
    Dim arr As String() = {"Dave", "Eve", "Frank"}
+

          
+
    ' 複数の要素を追加する (配列に含まれている内容をすべて追加する)
+
    list.AddRange(arr)
+

          
+
    Print(list)
+
  End Sub
+

          
+
  Shared Sub Print(ByVal list As List(Of String))
+
    For Each e As String In list
+
      Console.Write("{0}, ", e)
+
    Next
+

          
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Alice, Charlie, 
+
Alice, Bob, Charlie, 
+
Alice, Bob, Charlie, Dave, Eve, Frank, 
+
}}
+

          
+
***列挙操作中の要素の追加
+
Listをforeach文で列挙している最中に要素の追加や削除などの変更を行おうとすると、例外InvalidOperationExceptionがスローされます。 これを回避するにはforeachの代わりにfor文や[[ForEachメソッド>#List_Enumeartion]]を使うようにします。 詳しくは[[programming/netfx/enumeration]]でも解説していますので適宜参照してください。
+

          
+

          
+
**要素の削除
+
要素を削除するには&msdn(netfx,member,System.Collections.Generic.List`1.Remove){Removeメソッド};や&msdn(netfx,member,System.Collections.Generic.List`1.RemoveAt){RemoveAtメソッド};を使います。 Removeメソッドでは''削除したい値''を指定し、RemoveAtメソッドでは''削除したい要素のインデックス''を指定します。 Removeメソッドでは、同じ値を持つ要素が複数ある場合、最初に見つかったものが削除されます。
+

          
+
範囲を指定して要素を削除するには&msdn(netfx,member,System.Collections.Generic.List`1.RemoveRange){RemoveRangeメソッド};を使うことが出来ます。 また、&msdn(netfx,member,System.Collections.Generic.List`1.Clear){Clearメソッド};を使うことでList内の全ての要素を削除することも出来ます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    List<int> list = new List<int>() {0, 1, 1, 1, 2, 2, 2, 3, 3};
+

          
+
    // 値1を持つ要素を削除する
+
    list.Remove(1);
 

        

        
 
    Print(list);
    Print(list);
 

        

        
~
    // インデックス2から要素3個を削除する
    // 特定の位置に要素を挿入
~
    list.RemoveRange(2, 3);
    list.Insert(2, 3);
 

        

        
 
    Print(list);
    Print(list);
 

        

        
~
    // インデックス4の要素を削除する
    // Listの内容をソート
~
    list.RemoveAt(4);
    list.Sort();
 

        

        
 
    Print(list);
    Print(list);
 

        

        
~
    // すべての要素をクリアして、要素を追加し直す
    // Listの内容を反転
~
    list.Clear();
    list.Reverse();
+
    list.AddRange(new int[] {4, 5, 6, 7});
 

        

        
 
    Print(list);
    Print(list);
 
  }
  }
320,329 91,57
 

        

        
 
Class Sample
Class Sample
 
  Shared Sub Main()
  Shared Sub Main()
~
    Dim list As New List(Of Integer)(New Integer() {0, 1, 1, 1, 2, 2, 2, 3, 3})
    Dim list As New List(Of Integer)()
 

        

        
~
    ' 値1を持つ最初の要素を削除する
    ' 要素の追加
~
    list.Remove(1)
    list.Add(0)
-
    list.Add(1)
-
    list.Add(2)
 

        

        
 
    Print(list)
    Print(list)
 

        

        
~
    ' インデックス2から要素3個を削除する
    ' 複数の要素の追加
~
    list.RemoveRange(2, 3)
    list.AddRange(New Integer() {3, 4, 5, 6})
 

        

        
 
    Print(list)
    Print(list)
 

        

        
~
    ' インデックス4の要素を削除する
    ' 要素の削除
~
    list.RemoveAt(4)
    list.Remove(3)
-
    list.Remove(6)
 

        

        
 
    Print(list)
    Print(list)
 

        

        
~
    ' すべての要素をクリアして、要素を追加し直す
    ' 特定の位置にある要素を削除
~
    list.Clear()
    list.RemoveAt(0)
+
    list.AddRange(New Integer() {4, 5, 6, 7})
 

        

        
 
    Print(list)
    Print(list)
+
  End Sub
 

        

        
~
  Shared Sub Print(ByVal list As List(Of Integer))
    ' 特定の位置にある要素を変更
~
    For Each e As Integer In list
    list(2) = 7
+
      Console.Write("{0}, ", e)
+
    Next
 

        

        
~
    Console.WriteLine()
    Print(list)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 1, 2, 2, 2, 3, 3, 
+
0, 1, 2, 3, 3, 
+
0, 1, 2, 3, 
+
4, 5, 6, 7,
+
}}
+

          
+
なお、[[RemoveAllメソッド>#List_Predicate]]を使うと条件を指定して要素を削除することが出来ます。
+

          
+

          
+
**要素の検索
+
List内に特定の要素が含まれているかどうかを調べるには&msdn(netfx,member,System.Collections.Generic.List`1.Contains){Containsメソッド};を使うことが出来ます。 また、List内のどこに含まれているかどうかを調べるには&msdn(netfx,member,System.Collections.Generic.List`1.IndexOf){IndexOfメソッド};を使うことが出来ます。 IndexOfメソッドでは、要素が見つかった場合はその要素のインデックスを返します。 もし見つからなければ-1が返されます。 IndexOfメソッドはListの先頭から調べて最初に見つかった要素のインデックスを返しますが、&msdn(netfx,member,System.Collections.Generic.List`1.LastIndexOf){LastIndexOfメソッド};を使うとListの末尾から調べて最初に見つかったインデックス(List内の一番最後にあるインデックス)を取得することが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    List<string> list = new List<string>() {"Alice", "Bob", "Charlie", "Bob", "Alice"};
+

          
+
    // 値"Bob"を持つ要素があるかどうか
+
    Console.WriteLine("Contains(Bob) : {0}", list.Contains("Bob"));
+

          
+
    // 値"Dave"を持つ要素があるかどうか
+
    Console.WriteLine("Contains(Dave) : {0}", list.Contains("Dave"));
+

          
+
    // 値"Bob"を持つ最初の要素の位置を取得する
+
    Console.WriteLine("IndexOf(Bob) = {0}", list.IndexOf("Bob"));
+

          
+
    // 値"Eve"を持つ最初の要素の位置を取得する
+
    Console.WriteLine("IndexOf(Eve) = {0}", list.IndexOf("Eve"));
+

          
+
    // 値"Alice"を持つ最後の要素の位置を取得する
+
    Console.WriteLine("LastIndexOf(Alice) = {0}", list.LastIndexOf("Alice"));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New List(Of String)(New String() {"Alice", "Bob", "Charlie", "Bob", "Alice"})
+

          
+
    ' 値"Bob"を持つ要素があるかどうか
+
    Console.WriteLine("Contains(Bob) : {0}", list.Contains("Bob"))
+

          
+
    ' 値"Dave"を持つ要素があるかどうか
+
    Console.WriteLine("Contains(Dave) : {0}", list.Contains("Dave"))
 

        

        
~
    ' 値"Bob"を持つ最初の要素の位置を取得する
    ' 特定の位置に要素を挿入
~
    Console.WriteLine("IndexOf(Bob) = {0}", list.IndexOf("Bob"))
    list.Insert(2, 3)
+

          
+
    ' 値"Eve"を持つ最初の要素の位置を取得する
+
    Console.WriteLine("IndexOf(Eve) = {0}", list.IndexOf("Eve"))
+

          
+
    ' 値"Alice"を持つ最後の要素の位置を取得する
+
    Console.WriteLine("LastIndexOf(Alice) = {0}", list.LastIndexOf("Alice"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Contains(Bob) : True
+
Contains(Dave) : False
+
IndexOf(Bob) = 1
+
IndexOf(Eve) = -1
+
LastIndexOf(Alice) = 4
+
}}
+

          
+
なお、[[Find等のメソッド>#List_Predicate]]を使うと、条件を指定して要素を検索することが出来ます。 また、文字列を格納するリストで大文字小文字を無視した検索をしたい場合などはこれらのメソッドを使う必要があります。
+

          
+

          
+
**配列への変換・コピー
+
Listを配列に変換する必要がある場合は、&msdn(netfx,member,System.Collections.Generic.List`1.ToArray){ToArrayメソッド};が使えます。 このメソッドでは、現在Listに格納されている内容をコピーした配列を返します。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    List<string> list = new List<string>() {"Alice", "Bob", "Charlie", "Dave", "Eve"};
+

          
+
    string[] arr;
+

          
+
    // Listの内容を配列に変換
+
    arr = list.ToArray();
+

          
+
    // 変換した配列の内容を表示
+
    Console.WriteLine("Length = {0}", arr.Length);
+

          
+
    foreach (string e in arr)
+
    {
+
      Console.WriteLine(e);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New List(Of String)(New String() {"Alice", "Bob", "Charlie", "Bob", "Alice"})
+

          
+
    Dim arr As String()
+

          
+
    ' Listの内容を配列に変換
+
    arr = list.ToArray()
+

          
+
    ' 変換した配列の内容を表示
+
    Console.WriteLine("Length = {0}", arr.Length)
+

          
+
    For Each e As String In arr
+
      Console.WriteLine(e)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Length = 5
+
Alice
+
Bob
+
Charlie
+
Bob
+
Alice
+
}}
+

          
+
なお、このメソッドでは''簡易コピー''が行われるため、参照型を要素に持つListの場合は参照のみがコピーされます。 簡易コピーについてより詳しくは[[programming/netfx/cloning]]で解説しています。
+

          
+
また、Listの一部分だけを配列にコピーしたい場合は、&msdn(netfx,member,System.Collections.Generic.List`1.CopyTo){CopyToメソッド};を使うことが出来ます。 このメソッドではList全体を配列にコピーすることもできますが、ToArrayメソッドとは異なりあらかじめコピー先に配列を用意しておく必要があります。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    List<string> list = new List<string>() {"Alice", "Bob", "Charlie", "Dave", "Eve"};
+

          
+
    // コピー先の配列を用意
+
    string[] arr = new string[5];
+

          
+
    // Listのインデックス2から3要素分を配列のインデックス0以降にコピー
+
    list.CopyTo(2, arr, 0, 3);
+

          
+
    Print(arr);
+

          
+
    // Listのインデックス0から2要素分を配列のインデックス3以降にコピー
+
    list.CopyTo(0, arr, 3, 2);
+

          
+
    Print(arr);
+
  }
+

          
+
  static void Print(string[] arr)
+
  {
+
    foreach (string e in arr)
+
    {
+
      Console.Write("{0}, ", e);
+
    }
+

          
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New List(Of String)(New String() {"Alice", "Bob", "Charlie", "Dave", "Eve"})
+

          
+
    ' コピー先の配列を用意
+
    Dim arr(4) As String
+

          
+
    ' Listのインデックス2から3要素分を配列のインデックス0以降にコピー
+
    list.CopyTo(2, arr, 0, 3)
+

          
+
    Print(arr)
+

          
+
    ' Listのインデックス0から2要素分を配列のインデックス3以降にコピー
+
    list.CopyTo(0, arr, 3, 2)
+

          
+
    Print(arr)
+
  End Sub
+

          
+
  Shared Sub Print(ByVal arr As String())
+
    For Each e As String In arr
+
      Console.Write("{0}, ", e)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Charlie, Dave, Eve, , , 
+
Charlie, Dave, Eve, Alice, Bob, 
+
}}
+

          
+

          
+
**並べ替え
+
&msdn(netfx,member,System.Collections.Generic.List`1.Sort){Sortメソッド};を使うことでList内の要素をソートすることが出来ます。 なお、大文字小文字を無視したソートや降順でのソートなど、Listクラスを使ったソートについては[[programming/netfx/sorting/0_basictypes]]や[[programming/netfx/sorting/1_compositetypes]]で詳しく解説しています。
+

          
+
また、&msdn(netfx,member,System.Collections.Generic.List`1.Reverse){Reverseメソッド};を使うことでList内の要素の並びを逆順にすることが出来ます。 SortメソッドとReverseメソッドを組み合わせることでソートした結果を降順にすることが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    List<int> list = new List<int>() {0, 2, 3, 1, 0, 1, 3, 1, 3};
+

          
+
    Print(list);
+

          
+
    // List内の要素をソート (昇順に並べ替える)
+
    list.Sort();
+

          
+
    Print(list);
+

          
+
    // List内の要素の並びを逆にする (降順にする)
+
    list.Reverse();
+

          
+
    Print(list);
+
  }
+

          
+
  static void Print(List<int> list)
+
  {
+
    foreach (int e in list)
+
    {
+
      Console.Write("{0}, ", e);
+
    }
+

          
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New List(Of Integer)(New Integer() {0, 2, 3, 1, 0, 1, 3, 1, 3})
 

        

        
 
    Print(list)
    Print(list)
 

        

        
~
    ' List内の要素をソート (昇順に並べ替える)
    ' Listの内容をソート
 
    list.Sort()
    list.Sort()
 

        

        
 
    Print(list)
    Print(list)
 

        

        
~
    ' List内の要素の並びを逆にする (降順にする)
    ' Listの内容を反転
 
    list.Reverse()
    list.Reverse()
 

        

        
 
    Print(list)
    Print(list)
 
  End Sub
  End Sub
 

        

        
~
  Shared Sub Print(ByVal arr As List(Of Integer))
  Shared Sub Print(ByVal list As List(Of Integer))
~
    For Each e As Integer In arr
    For Each e As Integer In list
 
      Console.Write("{0}, ", e)
      Console.Write("{0}, ", e)
 
    Next
    Next
-

          
 
    Console.WriteLine()
    Console.WriteLine()
 
  End Sub
  End Sub
 
End Class
End Class
650,67 149,23
 
#tabpage-end
#tabpage-end
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
~
0, 2, 3, 1, 0, 1, 3, 1, 3, 
0, 1, 2, 
~
0, 0, 1, 1, 1, 2, 3, 3, 3, 
0, 1, 2, 3, 4, 5, 6, 
~
3, 3, 3, 2, 1, 1, 1, 0, 0, 
0, 1, 2, 4, 5, 
~
}}
1, 2, 4, 5, 
~

          
1, 2, 7, 5, 
~

          
1, 2, 3, 7, 5, 
~
**読み取り専用
1, 2, 3, 5, 7, 
~
&msdn(netfx,member,System.Collections.Generic.List`1.AsReadOnly){AsReadOnlyメソッド};を使うと、Listを読み取り専用にしたコレクション(&msdn(netfx,type,System.Collections.ObjectModel.ReadOnlyCollection`1){ReadOnlyCollection};)を取得することが出来ます。 このメソッドを使って作成した読み取り専用のコレクションに対しては要素の追加・削除・変更を行うことが出来ません(行おうとするとNotSupportedExceptionがスローされます)。
7, 5, 3, 2, 1, 
+

          
+
なお、このメソッドでは元のListを読み取り専用にする訳ではないので注意してください。 元になったListは、依然として要素の追加・削除・変更が可能です。 ReadOnlyCollectionについて詳しくは[[programming/netfx/collections/3_objectmodel_1_collection#ReadOnlyCollection]]を参照してください。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    List<string> list = new List<string>() {"Alice", "Bob", "Charlie", "Dave", "Eve"};
+

          
+
    // 読み取り専用にしたものをIListとして格納する
+
    IList<string> readOnlyList = list.AsReadOnly();
+

          
+
    // IList.Addメソッドを使って要素の追加を試みる
+
    readOnlyList.Add("Frank");
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New List(Of String)(New String() {"Alice", "Bob", "Charlie", "Dave", "Eve"})
+

          
+
    ' 読み取り専用にしたものをIListとして格納する
+
    Dim readOnlyList As IList(Of String) = list.AsReadOnly()
+

          
+
    ' IList.Addメソッドを使って要素の追加を試みる
+
    readOnlyList.Add("Frank")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
ハンドルされていない例外: System.NotSupportedException: コレクションは読み取り専用です。
+
   場所 System.Collections.ObjectModel.ReadOnlyCollection`1.System.Collections.Generic.ICollection<T>.Add(T value)
+
   場所 Sample.Main()
 
}}
}}
 

        

        
-
ただ、単にジェネリックなArrayListというわけではなく、ArrayListと比べるとより高度な操作が可能になっています。
 

        

        
~
*デリゲートを用いた操作
**ソート
~
Listクラスでは、Listの要素に対する操作をメソッドとして記述しておき、それを[[デリゲート>programming/netfx/delegate]]の形で渡すことで高度な操作を行うことが出来るようになっています。
Listクラスのソートについては[[programming/netfx/sorting/0_basictypes]]や[[programming/netfx/sorting/1_compositetypes]]で詳しく解説しています。
 

        

        
 
**述語(Predicate)を用いた検索 [#List_Predicate]
**述語(Predicate)を用いた検索 [#List_Predicate]
~
Listクラスでは、述語(Predicateデリゲート)を用いた検索・一致の検証が行えます。 条件式を記述したメソッドを一種の引数として渡すことで、その条件に合致する要素が存在するかどうか、といった操作が出来るようになります。 例えば、Containsメソッドでは引数で指定した要素が含まれているかどうかは調べられますが、''どのような''要素が含まれているかという''条件''を指定することは出来ません。 対してExistsメソッドでは、「文字列の長さが5以上の」や「数値の大きさが16未満の」といった条件を指定した上で、それに合致する要素が含まれているかどうかを調べることが出来ます。
Listクラスでは、述語(Predicateデリゲート)を用いた検索・一致の検証が行えます。 条件式を記述したメソッドを一種の引数として渡すことで、その条件に合致する要素が存在するかどうか、といった操作が出きるようになります。 例えば、Containsメソッドでは引数で指定した要素が含まれているかどうかは調べられますが、''どのような''要素が含まれているかという''条件''を指定することは出来ません。 対してExistsメソッドでは、「文字列の長さが5以上の」や「数値の大きさが16未満の」といった条件を指定した上で、それに合致する要素が含まれているかどうかを調べることが出来ます。
 

        

        
 
Listクラスの次のメソッドでは、Predicateデリゲートを引数として渡すことで、述語で記述した条件にあう要素の検索などが行えます。
Listクラスの次のメソッドでは、Predicateデリゲートを引数として渡すことで、述語で記述した条件にあう要素の検索などが行えます。
 

        

        
1084,8 539,7
 
evE
evE
 
}}
}}
 

        

        
~

          
**入れ子 [#List_Nest]
+
*入れ子 [#List_Nest]
 
List<T>は任意の型Tに型付けしたリストを作成できるため、TにList<T>を指定すれば入れ子になったリストList<List<T>>を作成することが出来ます。 例えば可変長のジャグ配列のようなものを作成したい場合は、Listを入れ子にすることで実現できます。 入れ子になったListを列挙する場合、例えばList<List<int>>を列挙すると、List<List<int>>に含まれているList<int>を一つずつ取り出せます。
List<T>は任意の型Tに型付けしたリストを作成できるため、TにList<T>を指定すれば入れ子になったリストList<List<T>>を作成することが出来ます。 例えば可変長のジャグ配列のようなものを作成したい場合は、Listを入れ子にすることで実現できます。 入れ子になったListを列挙する場合、例えばList<List<int>>を列挙すると、List<List<int>>に含まれているList<int>を一つずつ取り出せます。
 

        

        
 
次の例では、入れ子になったListを作成し、追加や削除・列挙などの操作を行っています。
次の例では、入れ子になったListを作成し、追加や削除・列挙などの操作を行っています。