Dictionary 有一个ContainsKey方法,该方法的作用就是检查键值对中是否存在该键。今天在使用时,遇到了点小麻烦:Dictionary <List<int>,int> mydic=new Dictionary<List<int>,int>();
 List<int> data = new List<int>();            data.Add(1);
            data.Add(2);
            data.Add(3);   mydic.Add(data,0);   //然后新建一个Lis<int>  用ContainsKey 检查   用了两种方法:
 //方法一:
  List<int> newData=new List<int>();
  data.Foreach(x=>newData.Add(x));   if(mydic.ContainsKey(newData))
  {
          Console.Write("存在");
  }
   //方法二:
    List<int> newData=new List<int>();
    newData=data;   if(mydic.ContainsKey(newData))
  {
          Console.Write("存在");
  }
 结论:    只有第二中方法 打印出了存在。
问题:
    
  (1)ContainsKey 查找的本质是什么?
  (2)第一种方法与第二种方法的区别在哪里?
   (3) 第一种方法如何改进?

解决方案 »

  1.   

    ContainsKey 其实就是判断存在 key相等的元素, 最终都是进行key相等的判断
    而你这里key是List<int>,这个判断相等的依据是两个List的引用是否一样,而不是List里面的元素都相等
    事实上用List<int>做key毫无意义也达不到预想的效果
      

  2.   


    哦哦,我大概明白你的意思了。
    你看这种方式:
    Dictionary <int,int>  mydic =new Dictionary<int,int>();mydic.Add(1,5);   int value=1;
     if(mydic.ContainsKey(value))
    {
         Console.Write("存在,值为:{0}",mydic[value]);
    }
    else
    {
        Console.Write("不存在");}    对上述例子自己的想法:
          (1)  对于外界输入的任意值value , 通过ContainsKey即可判断出,该值存不存在于mydic 中,存在的话,就可获得相对应的值。
       
          (2) 上面这个例子,仅仅体现出了通过一个值找到另一个值,,有没有就想我最上面的那个帖子一样,通过两个值,或者多个值,获得相对应的值呢,,,所以自己斗胆试了试Dictionary<List<int>,int>  ,然后发现这种方式  好像并不理想
      

  3.   

    你可以从List<T>派生一个类,实现IEqualityComparer<T>接口
    然后实现Equals方法,在里面判断两个List的子元素是否完全相等
    这个类就可以做为key来判断了
      

  4.   

    注意如果类名是  xxxx<T>,接口将要是 IEqualityComparer<xxxx<T>>
      

  5.   

    (1)ContainsKey 查找的本质是什么?
    通过 key 判断是否存在,如果存在你可以给你的 LIST 加数据。  (2)第一种方法与第二种方法的区别在哪里?一个是查找,一个是赋值
       (3) 第一种方法如何改进?Dictionary <int,int>  mydic =new Dictionary<int,int>();
     
    mydic.Add(1,5);
     
       int value=1;
     if(mydic.ContainsKey(value))
    {
       //如果存在可以
    mydic[value]).Add(你的值);
    }
    else
    {
        //不存在
    mydic[value]) = new List<int>(){ 你的值 };
     
    }
      

  6.   

    key 分为值类型和引用类型,值类型比较的是二者的值,引用类型比较的是二者的地址,即使引用类型内容完全相同但地址不同,那也是不同的 key(string 类型除外)。List<int>显然是引用类型。
      

  7.   

    修正后的。      System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<int>> mydic = new System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<int>>();            mydic.Add(1, new System.Collections.Generic.List<int>() { 你的值 });            int value = 1;
                if (mydic.ContainsKey(value))
                {
                    //如果存在可以
                    mydic[value].Add(你的值);
                }
                else
                {
                    //不存在
                    mydic[value] = new System.Collections.Generic.List<int>() { 你的值 };            }
      

  8.   

    看你的 KEY 最好用 简单类型,如果用 LIST<int> 可以 去到他 TypeID 然后进行处理。
      

  9.   

    List<t> 是对象,两个对象是不相等的。
      

  10.   

    写一个只定义相等比较器,比较LIST<INT>的相等性
      

  11.   

    不特别指定的话,ContainsKey 方法使用默认的比较器,对于 List<T> 这种引用类型,比较的是引用是否相同。
      

  12.   

    Dim ss As String
            ss = "123"
            Dim a As New Dictionary(Of String, String)
            a.Item(ss) = ""        Dim sss As String
            sss = "123"
            msgbox(a.ContainsKey(sss))
    哪字符串也是引用类型,为什么这个就返回 true呢
      

  13.   

    字符串比较特殊,凡是内容完全相同的字符串,在内存中只有一份,即上述中的 ss 和 sss 虽然是两个变量,但内容完全相同,故二者引用了同一个地址。
      

  14.   

    兄弟,你可以试着分别改变方法一和方法二里面的newdata里面的值(增删改都行),再去看看data里面的值变了没有。
    结果是第一种不会变,第二种会跟着变化。
    比较2个引用类型是否相等不是比较内容一致,而是比较引用地址呀。所以第一种newdata!=data,所以找不到
      

  15.   

    先看看https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.dictionary-2?view=netframework-4.8
    TKey是数组,当然是引用类型,比较的是地址,而不是里面的值
      

  16.   

    一个数组做key?究竟是什么样的需求啊
      

  17.   

    如果实在要用 List《int》做key的话建议新建一个类型,然后list《int》继承之,然后将这个类型的gethashcode与equal方法重写