摘要:C#資料群集系列菜單-『串列(List)』
韋小寶:皇上啊~小的有一事想問~
皇上:準~說吧何事想問。
韋小寶:小的家有七個老婆,但要決定『進行遺傳學生殖方法的管理』有點煩惱啊。
韋小寶:皇上後官有三千,而且類型不同~ 屬性也不同~如同人間天堂啊~
韋小寶:小的想問問皇上,如何管理呢~~???
皇上:愛卿這問題非常有學問~朕好好和你談談~~
~本文主題~
『串列(List)的基本使用』
主要介紹串列(List)的是什麼與基本用法。
『IComparable』
主要介紹List排序方法使用的一種介面。
『IComparer』
同上
『List<T>的基本使用』
在.Net Framework具有一組collection類別,能夠處理新增及移除陣列元素時所引發的麻煩。
最常見的一種collection是List<T>串列。
List<T>的建立
你必預為串列裡要存放的項目指明『物件』或『值的型別』。
注意
<T>可以被取代為某種型別,所以List<string>代表由string構成的串列。
建立以string構成的串列
List test = new List< string>();
建立以Car類別構成的串列
List< Car> MyCar = new List< Car>();
Car類別程式碼
Car類別
//Car類別
public class Car
{
//建立speed欄位
private string speed;
//建立Speed屬性
public string Speed {
//get時回傳speed
get { return speed + "時束"; }
//set時傳入值進speed欄位
set
{
speed = value;
}
}
//Run方法
public string Run()
{
return "已時速" + speed + "的速度在跑中";
}
//覆寫ToString方法,修改成我們要的。
public override string ToString()
{
return "時速" + speed + "的車";
}
}
List<T>增加項目至串列裡。
//增加文字至串列test
test.Add( "1");
test.Add( "2");
test.Add( "3");
//增加物件至串列MyCar
MyCar.Add( new Car { Speed = "100" });
MyCar.Add( new Car { Speed = "50" });
List<T>抓取List裡的值
//輸出test[0]
Console.WriteLine(test[0]);
//輸出MyCar[0]
Console.WriteLine(MyCar[0]);
註:Console.WriteLine只是寫到資料輸出流裡喔。(應該沒人不知道)
執行結果
尋找List有沒有某某值
bool isIn = test.Contains("1");
Console.WriteLine(isIn);
串列聽起來很有用,那幹麻還要使用陣列
陣列佔用較少的記憶體空間,耗用較少的CPU資源。
假如你的程式是相當效能取向的,像是要處理同樣的操作
數百萬、數千萬次。那麼,用陣列而不是串列。
串列排序
想辦法為數字與字母排序並不難,只要下 MyCar.Sort();
他就會自動幫你排序,但是,如果在多重欄位中下Sort();
方法會發生什麼事呢???
要怎麼解決呢?? 我們這邊要介紹兩種Interface介面,來幫助你解決。
1.『IComparable』:嚴格來說IComparable<T>是幫助你的序列排序它。
2.『IComparer』:使用IComparer告訴你的串列如何排序。
『IComparable』
List.Sort()方法已經知道如何排序任何實作IComparable<T>介面的型別或類別,
該介面只有一個成員名為CompareTo()的方法。Sort()使用某物件的CompareTo()方法,
讓它與另一個物件作比較,並且利用該方法的回傳值(int)決定兩者的先後順序。
// 摘要:
// 定義通用的比較方法,實值型別或類別會實作這個方法,以建立型別特有的比較方法來排序執行個體。
//
// 型別參數:
// T:
// 要比較之物件的型別。
public interface IComparable
{
// 摘要:
// 將目前的執行個體與另一個具有相同型別的物件相比較。
//
// 參數:
// other:
// 要與這個物件相互比較的物件。
//
// 傳回:
// 值,表示所比較之物件的相對順序。 傳回值的意義如下: 值 意義 小於零 這個物件小於 other 參數。 Zero 這個物件等於 other。 大於零
// 這個物件大於 other。
int CompareTo(T other);
}
我們在這實作一個範例,來說明在多欄位下如何選擇欄位來進行排序
,首先在Car物件實作IComparable<Car>。
//Car類別
public class Car:IComparable< Car>
{
//建立speed欄位
private int speed;
private int power;
//建構子
public Car (int speed , int power)
{
this.speed = speed;
this.power = power;
}
//Run方法
public string Run()
{
return "已時速" + speed + "的速度在跑中";
}
//覆寫ToString方法,修改成我們要的。
public override string ToString()
{
return "時速" + speed + "的車";
}
//實作IComparable裡的CompareTo方法
//在(this.power > mycar.power )如果你要使用power欄位就代power
//如果你要使用speed作排序,就代speed.
public int CompareTo(Car mycar)
{
//this.speed表示為傳入值(現在這台車)
//假如這台車速度比較大,就傳回1
if (this .power > mycar.power )
return 1;
else if (this.power < mycar.power )
return -1;
else
return 0;
}
}
其中CompareTo為實作IComparable介面之方法,
下列程式碼,可以決定你想使用什麼欄位來進行排序。
if (this .power > mycar.power )
執行看看
private void button2_Click(object sender, EventArgs e)
{
//建立List物件 MyCar
List MyCar = new List< Car>();
MyCar.Add( new Car (100,20));
MyCar.Add( new Car (50,10));
MyCar.Add( new Car (10,5));
MyCar.Sort();
foreach (Car car in MyCar)
{
Console.WriteLine(car.ToString());
}
}
執行結果
要改成由小較大要只要將CompareTo方法改成下列程式碼,就解決。
//實作IComparable裡的CompareTo方法
public int CompareTo(Car mycar)
{
if (this .speed > mycar.speed)
return 1;
else if (this.speed < mycar.speed)
return -1;
else
return 0;
}
『IComparer』
NET Framework內建一個供List<T>使用的特殊介面,讓你建造獨立的類別,
來決定List<T>如何排序。藉由實作IComparer<T>介面裡的Compare()方法,
進行這項工作。
namespace System.Collections.Generic
{
// 摘要:
// 定義型別會實作其以比較兩個物件的方法。
//
// 型別參數:
// T:
// 要比較之物件的型別。
public interface IComparer
{
// 摘要:
// 比較兩個物件並傳回值,指出一個物件是小於、等於還是大於另一個物件。
//
// 參數:
// x:
// 要比較的第一個物件。
//
// y:
// 要比較的第二個物件。
//
// 傳回:
// 帶正負號的整數,表示 x 和 y 的相對值,如下表所示。 值 意義 小於零 x 小於 y。 Zero x 等於 y。 大於零 x 大於 y。
int Compare(T x, T y);
}
}
首先建立一個Car類別與上一支Car類別不同點在於,該類別沒有實作CompareTo方法,
但多建立排序類別CarComparerby。
//Car類別
public class Car
{
//建立speed欄位
private int speed;
private int power;
public int Speed
{
get { return speed; }
set { speed = value ; }
}
public int Power
{
get { return power; }
set { power = value ; }
}
//建構子,初初化
public Car (int speed , int power)
{
this.speed = speed;
this.power = power;
}
//Run方法
public string Run()
{
return "已時速" + speed + "的速度在跑中";
}
//覆寫ToString方法,修改成我們要的。
public override string ToString()
{
return "時速" + speed + "的車" + "馬力" + power ;
}
}
建立排序類別CarCompareby並實作IComaprer介面。
規則為先依Speed欄位由小排到大,如果Speed皆相等,
則在依Power欄位排序。
//建立一個排序類別
public class CarComparerby : IComparer
{
//實作Compare方法
//依Speed由小排到大。
public int Compare(Car x,Car y)
{
if (x.Speed < y.Speed)
return -1;
if (x.Speed > y.Speed)
return 1;
//該段為Speed相等時才會由Power比較
//依power由小排到大
if (x.Power < y.Power)
return -1;
if (x.Power > y.Power)
return 1;
return 0;
}
}
執行看看,其中Sort()方法,將依排序物件SortCar來決定排序方法。
private void button2_Click(object sender, EventArgs e)
{
//建立List物件 MyCar
List MyCar = new List< Car>();
MyCar.Add( new Car (100,20));
MyCar.Add( new Car (50,10));
MyCar.Add( new Car (50,5));
MyCar.Add( new Car (42,20));
//實體化排序類別為SortCar物件
CarComparerby SortCar = new CarComparerby();
//Sort方法會依序排序物件SortCar來決定排序方法。
MyCar.Sort(SortCar);
foreach (Car car in MyCar)
{
Console.WriteLine(car.ToString());
}
}
執行結果