IndexedSet是UGUI的内部类(internal class),是一个不会存在相同对象的表,如果有需要的话可以直接复制一份到工程里。
按照惯例,附上UGUI源码下载地址。
主要看这些代码:
readonly List<T> m_List = new List<T>();
Dictionary<T, int> m_Dictionary = new Dictionary<T, int>();
public void Add(T item)
{
if (m_Dictionary.ContainsKey(item))
return;
m_List.Add(item);
m_Dictionary.Add(item, m_List.Count - 1);
}
其实就是额外维护了一个m_Dictionary,item做key,item在m_List的下标做value。
Add方法很简单,但是Remove就稍微麻烦一点。
public bool Remove(T item)
{
int index = -1;
if (!m_Dictionary.TryGetValue(item, out index))
return false;
RemoveAt(index);
return true;
}
RemoveAt:
public void RemoveAt(int index)
{
T item = m_List[index];
m_Dictionary.Remove(item);
if (index == m_List.Count - 1)
m_List.RemoveAt(index);
else
{
int replaceItemIndex = m_List.Count - 1;
T replaceItem = m_List[replaceItemIndex];
m_List[index] = replaceItem;
m_Dictionary[replaceItem] = index;
m_List.RemoveAt(replaceItemIndex);
}
}
如果不是最后一个,把最后一个item移动到被移除的位置。这里需要注意,如果你的IndexedSet是有序的,在移除对象的之后,就有可能要重新排序了。
Sort: