第7章 數組和元組

1.區別:ios

  • 使用同一類型的多個對象 ==> 集合或數組
  • 使用不一樣類型的多個對象 ==> 元組(Tuple)

2.簡單數組:數組

  • 數組初始化:數組是引用類型,必須給它分配堆上的內存,應使用new運算符
    • 指定數組大小:int[] myArray = new int[4];
    • 使用初始化器賦值:int[] myArray = new int[4] {4, 7, 11, 2};
      • 簡化一:使用花括號初始化數據,可不指定數組的大小                          int[] myArray = new int[] {4, 7, 11, 2};
      • 簡化二:C#編譯器更簡化,使用花括號能夠同時聲明和初始化數組       int[] myArray = {4, 7, 11, 2};
  • 使用引用類型:能夠聲明自定義類型的數組
    • 數組元素是引用類型,就必須爲每一個數組元素分配內存
//自定義Person類
public class Person
{
    public string FirstName {get; set;}
    public string LastName {get; set;}
    
    public override string ToString() => $"{FirstName} {LastName}";
}    

//定義Person數組
Person[] myPersons = new Person[2];

//爲每一個數組元素分配內存
myPersons[0] = new Person {FirstName = "Ayrton", LastName="Senna"};
myPersons[1] = new Person {FirstName = "Michael", LastName="Schumacher"};
    • 使用數組初始化器賦值
Person[] myPersons2 = 
{
     new Person {FirstName = "Ayrton", LastName="Senna"},
     new Person {FirstName = "Michael", LastName="Schumacher"}
};

 3.多維數組:用兩個或多個整數來索引ide

  • 二維數組:
    • 聲明:須要在方括號中加上一個逗號; 
    • 初始化:
      • 應指定每一維的大小(也稱爲階)==> int[,] twodim = new int[3,3];
      • 使用數組索引器
int[,] towdim = {
                  {1, 2, 3},
                  {4, 5, 6},
                  {7, 8, 9},
                };
  • 三維數組:在花括號中使用兩個逗號聲明
int[,,] threedim = {
                  { {1, 2},  {3, 4} },
                  { {5, 6},  {7, 8} },
                  { {9, 10},  {11, 12} }
                };
WriteLine(threedim[0, 1, 1]);

 

4. 鋸齒數組:每一行均可以有不一樣的大小。spa

  • 聲明時要依次放置左右括號
  • 初始化時只對第1對方框中設置數組行數。
  • 定義每行時再指定元素個數
int[][] jagged = new int[3][];
jagged[0] = new int[2] {1, 2};
jagged[1] = new int[6] {3, 4, 5, 6, 7, 8};
jagged[2] = new int[3] {9, 10, 11};

 

5. Array類:用方括號聲明數組是C#中使用Array類的表示法.net

  • Length屬性或foreach語句迭代數組,使用了Array類中的GetEnumerator()方法
  • LongLength屬性:數組元素個數超出整數的取值範圍,使用此屬性得到元素個數
  • Rank屬性:得到數組的維數
  • 建立數組:
    • CreateInstance()建立是事先不知道元素類型的數組
    • SetValue()設置對應元素的值
    • GetValue()讀取對應元素的值
//建立類型爲int、大小爲5的一維數組
Array intArray1 = Array.CreateInstatnce(typeof(int), 5);

//強制轉換成聲明爲int[]的數組
int[] intArray2 = (int[])intArray1;

//建立類型爲Person,大小爲2*3個元素的二維數組
//且第一維基於1,第二維基於10
int[] lengths = {2, 3};
int[] lowerBounds = {1, 10};
Array racers = Array.CreateInstance(typeof(Person), lengths, lowerBounds);
  •  複製數組:
    • 實現ICloneable接口,使用Clone()方法建立數組的淺表副本,即建立一個新數組。
      • 數組元素是值類型,值複製全部值。
      • 數組元素是引用類型,則不復制元素,只複製引用。
    • Array.Copy()也能夠建立淺表副本,但必須傳遞階數相同且有足夠元素的已有數組。
  • 排序:

    • 數組使用自定義類型應實現接口有兩種方式:
      • 實現IComparable接口,重寫CompareTo()方法 ==> 就是在告訴你們,我實現了這個接口,全部個人實例都是能夠比較的,而且比較的規則是按照我實現的IComparable中的方法CompareTo來進行的。
      • 實現IComparer接口或IComparer<T>接口,重寫Compare()方法。該接口獨立於要比較的類,須要兩個要比較的參數。

                           註明:詳細可參考 原文:https://blog.csdn.net/ios99999/article/details/77800819code

    •  舉例說明實現以上兩種接口的自定義類型數組使用Sort()排序方法
      • 實現IComparable接口
//自定義Person類
public class Person : IComparable<Person>
{
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public override string ToString() => $"{FirstName} {LastName}";

        public int CompareTo(Person other)
        {
            if (other == null) throw new ArgumentNullException("other");

            int result = LastName.CompareTo(other.LastName);
            if (result == 0)
            {
                result = FirstName.CompareTo(other.FirstName);
            }

            return result;
        }
}


//數組排序
Person[] persons =  {
                new Person { FirstName="Damon", LastName="Hill" },
                new Person { FirstName="Niki", LastName="Lauda" },
                new Person { FirstName="Ayrton", LastName="Senna" },
                new Person { FirstName="Graham", LastName="Hill" }
             };
            Array.Sort(persons);
            foreach (Person p in persons)
            {
                WriteLine(p);
            }

//排序結果
//Damon Hill
//Graham Hill
//Niki Lauda
//Ayrton Senna
      • 實現IComparer<T>接口
//自定義PersonComparer類
//定義了排序選項
public enum PersonCompareType
{
        FirstName,
        LastName
}

public class PersonComparer : IComparer<Person>
{
        private PersonCompareType _compareType;
        
        public PersonComparer(PersonCompareType compareType)
        {
            _compareType = compareType;  //肯定排序方式
        }

        #region IComparer<Person> Members
        // 可根據排序方式靈活進行排序
        public int Compare(Person x, Person y)
        {
            if (x == null && y == null) return 0;
            if (x == null) return 1;
            if (y == null) return -1;

            switch (_compareType)
            {
                case PersonCompareType.FirstName:
                    return string.Compare(x.FirstName, y.FirstName);
                case PersonCompareType.LastName:
                    return string.Compare(x.LastName, y.LastName);
                default:
                    throw new ArgumentException(
                          "unexpected compare type");
            }
        }

        #endregion
}

//自定義類型數組排序,根據FirstName排序
Array.Sort(persons,
                new PersonComparer(PersonCompareType.FirstName));

foreach (Person p in persons)
{
      WriteLine(p);
}

//排序結果
//Ayrton Senna
//Damon Hill
//Graham Hill
//Niki Lauda

 6. 數組做爲參數:數組能夠做爲參數傳遞給方法,也能夠從方法返回對象

  • 數組支持協變:便可以聲明一個基類參數(如object[]類型),給它傳遞一個派生類型(如Person[])。數組協變只能用於引用類型。
  • 部分數組:結構ArraySegment<T>表示數組的一段。能夠將整個數組的某些部分傳遞給不一樣的方法。參數包括數組,偏移量和該方法使用的元素數
//計算數組段定義的全部整數之和
static int SumOfSegments(ArraySegment<int>[] segments)
{
            int sum = 0;
            foreach (var segment in segments)
            {
                for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
                {
                    sum += segment.Array[i];
                }

            }
            return sum;
}

//使用方法
//計算數組ar1從第1個元素開始,引用3個元素;
//計算數組ar2從第3個元素開始,引用3個元素;
int[] ar1 = { 1, 4, 5, 11, 13, 18 };
int[] ar2 = { 3, 4, 5, 18, 21, 27, 33 };
var segments = new ArraySegment<int>[2]
{
      new ArraySegment<int>(ar1, 0, 3),
      new ArraySegment<int>(ar2, 3, 3)
};

// sum = 1 + 4 + 5 + 18 + 21 + 27
var sum = SumOfSegments(segments);
WriteLine($"sum of all segments: {sum}");

 7. 枚舉:使用foreach語句實現迭代,是因爲其使用了枚舉器blog

  •  一個類型是否支持foreach遍歷,必須知足下面兩個條件:
    • 這個類實現IEnumerable接口
    • 這個類有一個public的GetEnumerator的實例方法,而且返回類型中(IEnumerator)具備public 的bool MoveNext()方法和public的Current屬性
  • IEnumerable接口與IEnumerator接口區別:
    • IEnumerable   可迭代的,能夠說是一個聲明式的接口,但沒有具體如何實現迭代器(iterator),僅有可返回IEnumerator 類型的方法
    • IEnumerator    迭代器,經過實現該接口就能夠做爲一個迭代器(iterator),包含了具體的須要實現的方法

      註明: 詳細可參考 原文:https://blog.csdn.net/i1tws/article/details/51511134?utm_source=copy排序

  • yield語句:便於建立枚舉器,其必須聲明爲返回IEnumerator或IEnumerable接口
    • yield return:返回集合的一個元素
    • yield break:可中止迭代
    • 可使用yield return語句,以不一樣方式迭代集合的類
    • yield return返回枚舉器

8.元組:用於合併不一樣類型的對象。索引

  • .NET Framework定義了8個泛型Tuple類和1個靜態Tuple類。
  • 元組用靜態Tuple類的靜態Create()方法建立。

9.結構比較:數組和元組都實現接口IStructuralEquatable和IStructuralComparable

  • IStructuralEquatable:比較兩個元組或數組是否有相同的內容
  • IStructuralComparable:用於給元組或數組排序
相關文章
相關標籤/搜索