AddOrUpdate 不更新

AddOrUpdate not updating

我有一个<byte[], int>

类型的并发字典_dict

我遍历另一个字符串列表 (list1) 的项目,如果该项目作为键存在于 _dict 中,我增加它的值;如果没有,我将它添加到 _dict 并将其值设置为 1

foreach(byte[] item in list1)
{
  _dict.AddOrUpdate(item, 1, (key, oldValue) => oldValue + 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);
            }
        }
    }
}

使用 byte[] 作为字典键是个坏主意,因为将通过引用而不是内部数据来比较两个不同的字节数组。所以,如果你强烈需要 byte[] 作为字典键,你应该为 IEqualityComparer 接口编写自己的 class 。例如:

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);
  }
}

由于您已将键类型从 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