记一次SortedDictionary的不当使用

时间:2021-01-29 20:45:07

起初想用SortedDictionary做游戏中的排行榜,代码如下:

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic; public class CustomComparer<T> : IComparer<T>
{
Func<T, T, int> mComparerFunc; public CustomComparer(Func<T, T, int> comparer)
{
this.mComparerFunc = comparer;
} public int Compare(T x, T y)
{
return mComparerFunc(x, y);
}
} public class SortedDictTest : MonoBehaviour
{
SortedDictionary<string, int> mLeaderboard; void Start()
{
mLeaderboard = new SortedDictionary<string, int>(new CustomComparer<string>((x, y) => mLeaderboard[x].CompareTo(mLeaderboard[y]))); mLeaderboard.Add("Jhon", );
mLeaderboard.Add("Dark", );
mLeaderboard.Add("Ellie", ); foreach (var item in mLeaderboard)
{
Debug.Log("Name: " + item.Key + " Score: " + item.Value);
}
}
}

结果就是unity死循环

记一次SortedDictionary的不当使用

当你get字典中的数值时,它会调用比较器。比较器里又调用了字典,造成死循环

而且这种用法还有一个问题,可排序字典是对key进行排序,操作时内部有类似二分查找的机制。

在做排行榜时又要按名称匹配,又要自动按分数排序,此时是两套排序机制,字典内部顺序混乱,查找速度反而更慢。

解决方法也是有的,使用双字典可以解决:

public class SortedDictTest : MonoBehaviour
{
Dictionary<string, int> mScoreDict;
SortedDictionary<string, int> mLeaderboard; void Start()
{
mScoreDict = new Dictionary<string, int>();
mLeaderboard = new SortedDictionary<string, int>(new CustomComparer<string>((x, y) => mScoreDict[x].CompareTo(mScoreDict[y]))); mScoreDict.Add("Jhon", );
mScoreDict.Add("Dark", );
mScoreDict.Add("Ellie", ); mLeaderboard.Add("Jhon", );
mLeaderboard.Add("Dark", );
mLeaderboard.Add("Ellie", ); foreach (var item in mLeaderboard)
{
Debug.Log("Name: " + item.Key + " Score: " + item.Value);
}
}
}

记一次SortedDictionary的不当使用

具体看数据量多少来权衡,直接使用List排序也未尝不可