C# 复合字典,两个(多个)key值对应一个value,或者一个key对应多个value

问题背景

最近遇到个问题,Dictionary字典存储的时候需要根据两个key,才能确定一个具体的value值。

ConcurrentDictionary和Dictionary

由于是在线程上进行操作,我用到的字典是ConcurrentDictionary,区别于普通的Dictionary。(这里也是一开始使用Dictionary,然后遇到跨线程问题,抛出异常,所以相比之下选择了ConcurrentDictionary)

在C#中,Dictionary是一个常见的字典类型,但它不是线程安全的。为了在多线程环境中确保安全的操作,我们可以使用ConcurrentDictionary,这是一个专门设计用于多线程场景的线程安全字典。

ConcurrentDictionary提供了内置的线程安全机制,避免了多线程同时访问时的问题。

所以,单线程建议用Dictionary,多线程建议用ConcurrentDictionary

1.两个key对应一个value

1)可以使用双重字典,即字典里面嵌套字典的方式实现

//Dictionary<key1, Dictionary<key2, value>> dict1 = new System.Collections.Generic.Dictionary<key1, Dictionary<key2, value>>();
Dictionary<string, Dictionary<string, string>> dict1 = new Dictionary<string, Dictionary<string, string>>();

Dictionary<string, Dictionary<string, string>> dict1 = new Dictionary<string, Dictionary<string, string>>();

        /// <summary>
        /// 赋值
        /// </summary>
        public void SetValue(string key1, string key2, string value)
        {
            if (dict1.ContainsKey(key1))
            {
                Dictionary<string,string> dict2 = dict1[key1];
                if (dict2.ContainsKey(key2))
                    dict2[key2] = value;
                else
                    dict2.Add(key2, value);
            }
            else
            {
                Dictionary<string,string> dict2 = new Dictionary<string, string>();
                dict2.Add(key2, value);
                dict1.Add(key1, dict2);
            }
        }

        /// <summary>
        /// 取值
        /// </summary>
        public string GetValue(string key1, string key2, string defaultValue="")
        {
            if (dict1.ContainsKey(key1))
            {
                Dictionary<string, string> dict2 = dict1[key1];
                if (dict2.ContainsKey(key2))
                    return dict2[key2];
            }
            return defaultValue;
        }

2)也可以使用Tuple 二元组

 ConcurrentDictionary<Tuple<string, string>, string> pMultiDict = new ConcurrentDictionary<Tuple<string, string>, string>();
        public void MutilDict(string pkey1,string pkey2,string pvalue)
        {
            //取值
            string value = pMultiDict[new Tuple<string, string>(pkey1, pkey2)];
            //添加
            pMultiDict.TryAdd(new Tuple<string, string>(pkey1, pkey2), pvalue);

            //删除
            pMultiDict.TryRemove(new Tuple<string, string>(pkey1, pkey2), out string outValue);
            //更新
            pMultiDict.TryUpdate(new Tuple<string, string>(pkey1, pkey2), pvalue,value);
        }

2.一个key对应多个value

 /// <summary>
        /// 复合字典 一键多值   用来存储 一个key对应多个value的情况
        /// </summary>
        /// <param name="mutilValueDict"></param>
        /// <param name="pkey">key</param>
        /// <param name="pvalue">value</param>
        /// <param name="valueList"></param>
        /// <param name="pMethod">add/removeKey/removeValue</param>
        private void MultiValueDict(ConcurrentDictionary<string, List<string>> pMutilValueDict, List<string> pValueList, string pkey, string pvalue, string pMethod)
        {
            try
            {
                //赋值给临时字典,列表 进行操作
                ConcurrentDictionary<string, List<string>> mutilValueDict = pMutilValueDict;
                List<string> valueList = pValueList;
                switch (pMethod)
                {
                    case "add":
                        //add
                        if (mutilValueDict.ContainsKey(pkey))
                        {
                            List<string> tempList = mutilValueDict[pkey];
                            if (!tempList.Contains(pvalue))
                            {
                                tempList.Add(pvalue);
                            }
                            mutilValueDict.AddOrUpdate(pkey, tempList, (oldKey, oleValue) => tempList);
                        }
                        else
                        {
                            List<string> tempList = new List<string>();
                            tempList.Add(pvalue);
                            mutilValueDict.TryAdd(pkey, tempList);
                        }
                        if (!valueList.Contains(pvalue))
                        {
                            valueList.Add(pvalue);
                        }
                        break;
                    case "removeValue":
                        //remove
                        if (mutilValueDict.ContainsKey(pkey))
                        {
                            List<string> tempList = mutilValueDict[pkey];
                            if (tempList.Contains(pvalue))
                            {
                                tempList.Remove(pvalue);
                            }
                            mutilValueDict.AddOrUpdate(pkey, tempList, (mOldKey, mOldValue) => tempList);
                        }
                        if (valueList.Contains(pvalue))
                        {
                            valueList.Remove(pvalue);
                        }
                        break;
                    case "removeKey":
                        if (mutilValueDict.ContainsKey(pkey))
                        {
                            List<string> tempList = mutilValueDict[pkey];
                            foreach (string item in tempList)
                            {
                                valueList.Remove(item);
                            }
                            mutilValueDict.TryRemove(pkey, out List<string> list);
                        }
                        break;
                }
                //操作完成之后赋值
                MutliValueDict = mutilValueDict;
                MutliValueList = valueList;
            }
            catch (Exception e)
            {
                SaveLog("MultiValueDict操作失败" + e.Message + e.StackTrace);
            }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值