列表中的项目通过引用进行比较?

时间:2014-10-29 13:38:46

标签: c#

我有一个包含1000000个项目的列表,我需要确定一个项目是否在内部,但是通过引用。因此,我无法使用Contains,因为Contains并不总是通过引用匹配(例如,当列表类型string时)。我试过list.Any(x => object.ReferenceEquals),但这太慢了。

看看这里:

for(int i = 0; i < 1000000; i++)
{
  if(does list contains this item anotherList[i])
  {
    list.Add(anotherList[i]);
  }
}

我如何快速执行此操作?

1 个答案:

答案 0 :(得分:1)

使用带有IdendityEqualityComparer的字典来获取字典中的键比较以进行参考比较。这种方法与你的方法的主要区别在于你有一个O(1)查找,而不是你必须通过每个项目的整个列表得到的O(n)查找。

将以下代码放入示例Console应用程序项目中;它基本上将主词典分成两部分。

public class IdentityEqualityComparer<T> : IEqualityComparer<T> where T : class
{
    public int GetHashCode(T value)
    {
        return RuntimeHelpers.GetHashCode(value);
    }

    public bool Equals(T left, T right)
    {
        return left == right; // Reference identity comparison
    }
}

public class RefKeyType
{
    public int ID { get; set; }
}

class Program
{
    public static void Main()
    {
        var refDictionary = new Dictionary<RefKeyType, int>(1000000, new IdentityEqualityComparer<RefKeyType>());

        var testDictionary = new Dictionary<RefKeyType, int>(1000000, new IdentityEqualityComparer<RefKeyType>());

        var store = new Dictionary<RefKeyType, int>(1000000);

        for (var i = 0; i < 1000000; i++)
        {
            var key = new RefKeyType() {ID = i};

            refDictionary[key] = i;

            //Load the test dictionary if I is divisible by 2
            if (i%2 == 0)
            {
                testDictionary[key] = i;
            }
        }

        foreach (var key in refDictionary.Keys)
        {
            int val;
            if (!testDictionary.TryGetValue(key, out val))
            {
                store[key] = val;
            }
        }

        Console.WriteLine("Master dictionary has " + refDictionary.Count);
        Console.WriteLine("Test dictionary has " + testDictionary.Count);
        Console.WriteLine("Store dictionary has " + store.Count);
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();

    }
}