Unity 之?dāng)?shù)據(jù)集合解析

在日常開發(fā)中數(shù)據(jù)集合經(jīng)常的會用到窒升,使用頻率較高的例如 List 翼悴、Dictionary全度,在數(shù)據(jù)集合中每種數(shù)據(jù)結(jié)構(gòu)都有他們的優(yōu)缺點(diǎn)娶聘,所以今天筆者對常用的數(shù)據(jù)集合歸納整理灵临,一是防止自己忘記、二是希望能夠幫助到對此理解不清晰的開發(fā)者

筆者的Unity 開發(fā)版本為 2017.4.2.f2 (.NET 4.6)


有說的不準(zhǔn)確或者錯(cuò)誤的地方歡迎留言指正


Array

  • Array:在內(nèi)存上連續(xù)分配的趴荸,而且元素類型是一樣的
  • 優(yōu)點(diǎn):可以索引坐標(biāo)訪問 讀取快 缺點(diǎn):增刪慢儒溉,長度不變
            //Array:在內(nèi)存上連續(xù)分配的,而且元素類型是一樣的
            //優(yōu)點(diǎn):可以索引坐標(biāo)訪問  讀取快     缺點(diǎn):增刪慢发钝,長度不變
            int[] intArray = new int[3];
            intArray[0] = 0;
            string[] stringArray = new string[] { "菜鳥", "海瀾" };//Array

動(dòng)態(tài)數(shù)組(ArrayList)

  • ArrayList 不定長的顿涣,連續(xù)分配的;
  • 元素沒有類型限制酝豪,任何元素都是當(dāng)成object處理
  • 優(yōu)點(diǎn):讀取快 缺點(diǎn):增刪慢涛碑,如果是值類型,會有裝箱操作
            //ArrayList  不定長的孵淘,連續(xù)分配的蒲障;
            //元素沒有類型限制,任何元素都是當(dāng)成object處理
            //優(yōu)點(diǎn):讀取快            缺點(diǎn):增刪慢瘫证,如果是值類型揉阎,會有裝箱操作
            ArrayList arrayList = new ArrayList();
            arrayList.Add("菜鳥");
            arrayList.Add("海瀾");
            arrayList.Add(9257);//add增加長度

List 詳情請看MSDN備注中的性能相關(guān)

  • List:也是Array,內(nèi)存上都是連續(xù)擺放;不定長背捌;泛型毙籽,保證類型安全,避免裝箱拆箱
  • 優(yōu)點(diǎn):讀取快 缺點(diǎn):增刪慢
            //List:也是Array毡庆,內(nèi)存上都是連續(xù)擺放;不定長坑赡;泛型,保證類型安全么抗,避免裝箱拆箱
            //優(yōu)點(diǎn):讀取快      缺點(diǎn):增刪慢
            List<int> intList = new List<int>() { 1, 2, 3, 4 };
            intList.Add(5);
            intList.Add(6);

LinkedList

  • LinkedList:泛型的特點(diǎn);鏈表毅否,元素不連續(xù)分配,每個(gè)元素都有記錄前后節(jié)點(diǎn)
  • 節(jié)點(diǎn)值可以重復(fù)
  • 優(yōu)點(diǎn):增刪方便 缺點(diǎn):不能進(jìn)行下標(biāo)索引訪問蝇刀,找元素就只能遍歷 查找不方便
            LinkedList<int> linkedList = new LinkedList<int>();
            linkedList.AddFirst(123);
            linkedList.AddLast(456);

            bool isContain = linkedList.Contains(123);
            LinkedListNode<int> node123 = linkedList.Find(123);  //元素123的位置  從頭查找
            linkedList.AddBefore(node123, 123);
            linkedList.AddAfter(node123, 789);

Queue

  • 在鏈表的特點(diǎn)上添加先進(jìn)先出特點(diǎn)
            //Queue 就是鏈表  先進(jìn)先出  放任務(wù)延遲執(zhí)行螟加,A不斷寫入日志任務(wù)  B不斷獲取任務(wù)去執(zhí)行
            Queue<string> numbers = new Queue<string>();
            numbers.Enqueue("one");
            numbers.Enqueue("two");
            numbers.Enqueue("three");
            numbers.Enqueue("four");
            numbers.Enqueue("four");
            numbers.Enqueue("five");


Stack

Stack對應(yīng)MSDN地址

  • 在鏈表的基礎(chǔ)上添加先進(jìn)后出特點(diǎn)
            Stack<string> numbers = new Stack<string>();
            numbers.Push("one");
            numbers.Push("two");
            numbers.Push("three");
            numbers.Push("four");
            numbers.Push("five");//放進(jìn)去

HashSet

參考文章如下

HashTable、HashSet和Dictionary的區(qū)別

國外開發(fā)者HashTable熊泵、HashSet和Dictionary的比較文章

  • 這個(gè)HashSet就厲害了仰迁,hash分布,不僅僅能動(dòng)態(tài)擴(kuò)容、自動(dòng)去重顽分,而且還有交、叉施蜜、并卒蘸、補(bǔ)功能
            HashSet<string> hashSet = new HashSet<string>();
            hashSet.Add("1111");
            hashSet.Add("2222");
            hashSet.Add("3333");
            hashSet.Add("1111");
            hashSet.Add("1111");
            hashSet.Add("1111");
            Debug.Log($"第一次打印開始{new string('*', 20)}");
            foreach (var item in hashSet)
            {
                Debug.Log(item);
            }
            Debug.Log($"hashSet含有的Count為:{hashSet.Count}");

            Debug.Log($"第一次打印結(jié)束{new string('*', 20)}");
打印結(jié)果:
  • 對應(yīng)的交、補(bǔ)、并缸沃、補(bǔ)
            {
                HashSet<string> hashSet = new HashSet<string>();
                hashSet.Add("1111");
                hashSet.Add("2222");
                hashSet.Add("3333");
                hashSet.Add("A12435");
                hashSet.Add("B12435");
                hashSet.Add("C12435");

                HashSet<string> hashSet1 = new HashSet<string>();
                hashSet1.Add("1111");
                hashSet1.Add("1111");
                hashSet1.Add("1111");
                hashSet1.Add("2222");
                hashSet1.Add("3333");
                hashSet1.Add("a12435");
                hashSet1.Add("b12435");
                hashSet1.Add("c12435");

                HashSet<string> hashSet2 = new HashSet<string>();
                hashSet2.Add("1111");
                hashSet2.Add("1111");
                hashSet2.Add("1111");
                hashSet2.Add("2222");
                hashSet2.Add("3333");
                hashSet2.Add("a12435");
                hashSet2.Add("b12435");
                hashSet2.Add("c12435");

                HashSet<string> hashSet3 = new HashSet<string>();
                hashSet3.Add("1111");
                hashSet3.Add("1111");
                hashSet3.Add("1111");
                hashSet3.Add("2222");
                hashSet3.Add("3333");
                hashSet3.Add("a12435");
                hashSet3.Add("b12435");
                hashSet3.Add("c12435");

                HashSet<string> hashSet4 = new HashSet<string>();
                hashSet4.Add("1111");
                hashSet4.Add("1111");
                hashSet4.Add("1111");
                hashSet4.Add("2222");
                hashSet4.Add("3333");
                hashSet4.Add("a12435");
                hashSet4.Add("b12435");
                hashSet4.Add("c12435");

                Debug.Log("計(jì)算交集開始");
                hashSet1.IntersectWith(hashSet);//交集(hashSet1與hashSet共有的元素集合恰起,并賦值給hashSet1)
                foreach (var item in hashSet1)
                {
                    Debug.Log(item);
                }
                Debug.Log("計(jì)算交集結(jié)束");

                Debug.Log("計(jì)算補(bǔ)集開始");
                hashSet2.SymmetricExceptWith(hashSet);//補(bǔ)集(除共有意外的所有元素集合,并賦值給hashSet2)
                foreach (var item in hashSet2)
                {
                    Debug.Log(item);
                }
                Debug.Log("計(jì)算補(bǔ)集結(jié)束");

                Debug.Log("計(jì)算并集開始");
                hashSet3.UnionWith(hashSet);//并集(兩個(gè)集合含有的所有元素趾牧,并賦值給hashSet3)
                foreach (var item in hashSet3)
                {
                    Debug.Log(item);
                }
                Debug.Log("計(jì)算并集結(jié)束");

                Debug.Log("計(jì)算差集開始");
                hashSet4.ExceptWith(hashSet);//差集(hashSet1有而hashSet沒有的元素集合检盼,并賦值給hashSet4)
                foreach (var item in hashSet4)
                {
                    Debug.Log(item);
                }
                Debug.Log("計(jì)算差集結(jié)束");
            }

打印輸出


SortedSet

C#編程中HashSet和SortedSet的講解及區(qū)別

  • 也是有去重和交、叉翘单、并吨枉、補(bǔ)、功能哄芜,并且可自動(dòng)排序個(gè)自定義排序

IComparer<T> comparer 自定義對象要排序貌亭,就用這個(gè)指定

            SortedSet<string> sortedSet = new SortedSet<string>();
            sortedSet.Add("a123456");
            sortedSet.Add("b123456");
            sortedSet.Add("c123456");
            sortedSet.Add("12435");
            sortedSet.Add("12435");
            sortedSet.Add("12435");

            foreach (var item in sortedSet)
            {
                Debug.Log(item);
            }
打印信息

Hashtable

  • Hashtable key-value 體積可以動(dòng)態(tài)增加 根據(jù)key計(jì)算一個(gè)地址,然后在對應(yīng)的地址中放入key - value信息
  • object-裝箱拆箱問題 如果不同的key計(jì)算得到相同的地址认臊,則第二個(gè)在前面地址上 + 1
  • 查找的時(shí)候圃庭,如果地址對應(yīng)數(shù)據(jù)信息的key不對,那就 + 1查找(出現(xiàn)上面一條的情況下)
  • 優(yōu)點(diǎn):查找個(gè)數(shù)據(jù) 一次定位失晴; 增刪 一次定位剧腻; 增刪查改 都很快
  • 缺點(diǎn):浪費(fèi)了空間,Hashtable是基于數(shù)組實(shí)現(xiàn)涂屁,如果數(shù)據(jù)太多恕酸,造成重復(fù)相同地址(第二條),效率下降
            Hashtable table = new Hashtable();
            table.Add("123", "456");
            table[1] = 456;
            table[2] = 789;
            table[3] = 101112;
            table[1] = "0000";
            table["海瀾"] = 9257;
            foreach (DictionaryEntry objDE in table)
            {
                Debug.Log(objDE.Key.ToString());
                Debug.Log(objDE.Value.ToString());
            }
            //線程安全
            Hashtable.Synchronized(table);//只有一個(gè)線程寫  多個(gè)線程讀

Dictionary

出場率最高的key -value 數(shù)據(jù)集合胯陋,也是大家很熟悉的
  • 字典:泛型蕊温;key - value,增刪查改 都很快遏乔;有序的
  • 典不是線程安全 安全字典用ConcurrentDictionary
            Dictionary<int, string> dic = new Dictionary<int, string>();
            dic.Add(5, "e");
            dic.Add(4, "d");
            dic.Add(3, "c");
            dic.Add(2, "b");
            dic.Add(1, "a");
            foreach (var item in dic)
            {
                Debug.Log($"Key:{item.Key}, Value:{item.Value}");
            }

SortedDictionary

  • 自動(dòng)排序
        SortedDictionary<int, string> dic = new SortedDictionary<int, string>();
        dic.Add(1, "a");
        dic.Add(5, "e");
        dic.Add(3, "v");
        dic.Add(2, "b");
        dic.Add(4, "d");
        dic[6] = "f";

        foreach (var item in dic)
        {
            Debug.Log($"Key:{item.Key}, Value:{item.Value}");
        }

打印結(jié)果:

SortedList

  • 自動(dòng)排序
        SortedList sortedList = new SortedList();//IComparer
        sortedList.Add("1", "a");
        sortedList.Add("2", "b");
        sortedList.Add("3", "c");

        var keyList = sortedList.GetKeyList();
        var valueList = sortedList.GetValueList();

        sortedList.TrimToSize();//用于最小化集合的內(nèi)存開銷
  • ConcurrentQueue 線程安全版本的Queue
  • ConcurrentStack線程安全版本的Stack
  • ConcurrentBag線程安全的對象集合
  • ConcurrentDictionary線程安全的Dictionary
  • BlockingCollection線程安全集合類

詳情查看System.Collections.Concurrent Namespace

最后附上相應(yīng)的[IDictionary選項(xiàng) - 性能測試 - SortedList與SortedDictionary vs. Dictionary與Hashtable义矛,不方便看的小伙伴可以用谷歌瀏覽器一鍵翻譯,翻譯比較準(zhǔn)確


IEnumerable補(bǔ)充

IEnumerable經(jīng)常會見到盟萨,都是知道他是迭代器凉翻,但是具體怎么個(gè)迭代,又有點(diǎn)可能說不清捻激,下面筆者舉個(gè)小例子

public class YieldDemo
{
    public IEnumerable<int> CustomEnumerable()
    {
        for (int i = 0; i < 10; i++)
        {
            yield return this.Get(i);
        }
    }

    public IEnumerable<int> Common()
    {
        List<int> intList = new List<int>();
        for (int i = 0; i < 10; i++)
        {
            intList.Add(this.Get(i));
        }
        return intList;
    }

    private int Get(int num)
    {
        Thread.Sleep(200);
        return num * DateTime.Now.Second;
    }
}
        Task.Run(()=> 
        {
            YieldDemo yieldDemo = new YieldDemo();
            foreach (var item in yieldDemo.CustomEnumerable())
            {
                Debug.Log(item);//按需獲取制轰,要一個(gè)拿一個(gè)
            }
            Debug.Log("*******************************************");
            foreach (var item in yieldDemo.Common())
            {
                Debug.Log(item);//先全部獲取,然后一起返還
            }
        });

效果如下:

它最主要的作用就是【按需逐步查詢胞谭,避免性能浪費(fèi)】【按需逐步查詢垃杖,避免性能浪費(fèi)】【按需逐步查詢,避免性能浪費(fèi)】丈屹,比如一個(gè)集合含有1000個(gè)元素调俘,目的是需要查詢到他的第二個(gè)元素伶棒,用yeild方法就可以省去而剩下的998次查詢,如果是多次查詢效率上的提升可想而知彩库。

在實(shí)際開發(fā)中如果查詢比較復(fù)雜肤无,例如使用List配飾Linq中的where是一個(gè)不錯(cuò)的選擇

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市骇钦,隨后出現(xiàn)的幾起案子宛渐,更是在濱河造成了極大的恐慌,老刑警劉巖眯搭,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窥翩,死亡現(xiàn)場離奇詭異,居然都是意外死亡坦仍,警方通過查閱死者的電腦和手機(jī)鳍烁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來繁扎,“玉大人幔荒,你說我怎么就攤上這事∈崦担” “怎么了爹梁?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長提澎。 經(jīng)常有香客問我姚垃,道長,這世上最難降的妖魔是什么盼忌? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任积糯,我火速辦了婚禮,結(jié)果婚禮上谦纱,老公的妹妹穿的比我還像新娘看成。我一直安慰自己,他們只是感情好跨嘉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布川慌。 她就那樣靜靜地躺著,像睡著了一般祠乃。 火紅的嫁衣襯著肌膚如雪梦重。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天亮瓷,我揣著相機(jī)與錄音琴拧,去河邊找鬼。 笑死寺庄,一個(gè)胖子當(dāng)著我的面吹牛艾蓝,可吹牛的內(nèi)容都是我干的力崇。 我是一名探鬼主播斗塘,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼赢织,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了馍盟?” 一聲冷哼從身側(cè)響起于置,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贞岭,沒想到半個(gè)月后八毯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞄桨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年话速,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芯侥。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泊交,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柱查,到底是詐尸還是另有隱情廓俭,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布唉工,位于F島的核電站研乒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏淋硝。R本人自食惡果不足惜雹熬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谣膳。 院中可真熱鬧竿报,春花似錦、人聲如沸参歹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽犬庇。三九已至僧界,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間臭挽,已是汗流浹背捂襟。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欢峰,地道東北人葬荷。 一個(gè)月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓涨共,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宠漩。 傳聞我的和親對象是個(gè)殘疾皇子举反,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容