我有<byte[], int>
list1
我遍历另一个字符串列表(_dict
)的项目,如果该项目作为_dict
中的键存在,我会增加其值;如果没有,我将其添加到foreach(byte[] item in list1)
{
_dict.AddOrUpdate(item, 1, (key, oldValue) => oldValue + 1);
}
并将其值设置为1
_dict
问题是,即使该项目已存在于_dict
中,它也会将其再次添加到 internal class someClass
{
public List<byte[]> list1 { get; set; }
public ConcurrentDictionary<byte[], int> dict1 { get; set; }
}
class Program
{
static void Main(string[] args)
{
someClass obj = new someClass();
if (obj.list1 != null && obj.list1.Count > 0)
{
foreach (byte[] item in obj.list1)
{
// upsert operation (add if string not in dictionary; update by incrementing count if it does exist)
obj.dict1.AddOrUpdate(item, 1, (key, oldValue) => oldValue + 1);
}
}
}
}
而不是更新。
我的代码出了什么问题?
更新了代码块
json_decode
答案 0 :(得分:2)
使用byte []作为字典键是个坏主意,因为两个不同的字节数组将通过引用而不是内部数据进行比较。因此,如果你强烈需要byte []作为字典键,你应该为IEqualityComparer接口编写自己的类。例如:
public class ByteArrayComparer : IEqualityComparer<byte[]> {
public bool Equals(byte[] x, byte[] y) {
if ( x == null || x == null ) {
return x.length == y.length;
}
return x.SequenceEqual(y);
}
public int GetHashCode(byte[] key) {
return key.Sum(b => b);
}
}
答案 1 :(得分:2)
由于您已将密钥类型从string
更改为byte[]
,现在您看到的行为是正确的(最初,问题包含string
个密钥)。
由于:
字典使用默认的IEqualityComparer
来比较密钥,在byte[]
的情况下,只是比较参考。
由于两个byte[]
数组是两个不同的对象,即使它们包含相同的元素,它们也会被视为不同的键。
考虑自己创建一个IEqualityComparer
实现并在此构造函数中使用它:
public ConcurrentDictionary(
IEqualityComparer<TKey> comparer
)
编辑: 这是一个有效的例子:
public class ByteArrayComparer : IEqualityComparer<byte[]>
{
public bool Equals(byte[] x, byte[] y)
{
if (x == null || y == null)
return false;
if(x.Length != y.Length)
return false;
return x.SequenceEqual(y);
}
public int GetHashCode(byte[] array)
{
unchecked
{
return array.Aggregate(17, (v, b) => v * 23 + b.GetHashCode(), v => v);
}
}
}
internal class someClass
{
public List<byte[]> list1 = new List<byte[]>();
public ConcurrentDictionary<byte[], int> dict1 = new ConcurrentDictionary<byte[], int>(new ByteArrayComparer());
}
void Main()
{
someClass obj = new someClass();
obj.list1.Add(new byte[] { 1, 2 });
obj.list1.Add(new byte[] { 1, 2 });
obj.list1.Add(new byte[] { 1, 2 });
obj.list1.Add(new byte[] { 2, 3 });
obj.list1.Add(new byte[] { 2, 3 });
obj.list1.Add(new byte[] { 3, 4 });
if (obj.list1 != null && obj.list1.Count > 0)
{
foreach (byte[] item in obj.list1)
{
// upsert operation (add if string not in dictionary; update by incrementing count if it does exist)
obj.dict1.AddOrUpdate(item, 1, (key, oldValue) => oldValue + 1);
}
}
}
obj.dict1的最终内容将是:
Key 01 02
Value 3
Key 02 03
Value 2
Key 03 04
Value 1