我想知道在.NET中是否有java.util.LinkedHashMap
的对应物?(也就是说,如果我访问一个元素,它们会自动(重新)按顺序排列。(布尔访问顺序))。
我想知道在.NET中是否有java.util.LinkedHashMap
的对应物?(也就是说,如果我访问一个元素,它们会自动(重新)按顺序排列。(布尔访问顺序))。
仅为读者澄清一下:LinkedHashMap只在使用特定的构造函数重载时才会表现出这种行为。通常,元素是以插入顺序维护的。(对我来说感觉有点奇怪,但没关系。)
我不认为.NET中有这样的类。使用一个元素的链表和一个从键到链表节点的字典,构建它不太困难。访问将包括获取链表节点、将其移动到头部并返回值。
如果您想要,我今晚或明天很乐意实现它 - 虽然可能没有完整的单元测试等。(完全测试集合是件费时的事情!)
通过一些谷歌搜索,似乎没有内置的C#等效于LinkedHashMap,但是有一些第三方选项可用。
我已经使用System.Collections.Specialized.OrderedDictionary作为LinkedHashMap的替代品,它对我来说是有效的。关于OrderedDictionary有什么我需要注意的吗?(是的,它不是泛型的,但它在.NET 2或更新版本中可用)
NHibernate有一个NHibernate.Util.LinkedHashMap实现。
如果您已经在代码中使用它,就像我一样,它可能会很方便。
我可能来晚了,但是我用C#实现了LinkedHashMap(Java)的等效物LinkedDictionary,代码如下:
public class LinkedDictionary<K, V> : IDictionary<K, V>, ICollection<KeyValuePair<K, V>>, IEnumerable<KeyValuePair<K, V>>
{
private List<K> list = new List<K>();
private Dictionary<K, V> dictionary = new Dictionary<K, V>();
public LinkedDictionary()
{
}
public V this[K key] {
get {
return this.dictionary[key];
}
set {
this.dictionary[key] = value;
if (!this.list.Contains(key))
{
this.list.Add(key);
}
}
}
public int Count => this.dictionary.Count;
public bool IsReadOnly => false;
ICollection<K> IDictionary<K, V>.Keys => this.list;
ICollection<V> IDictionary<K, V>.Values
{
get
{
List<V> values = new List<V>(this.dictionary.Count);
foreach(K key in this.list)
{
V value = default(V);
this.dictionary.TryGetValue(key, out value);
values.Add(value);
}
return values;
}
}
public void Add(KeyValuePair<K, V> item)
{
this.dictionary.Add(item.Key, item.Value);
if (!this.list.Contains(item.Key))
{
this.list.Add(item.Key);
}
}
public void Add(K key, V value)
{
this.dictionary.Add(key, value);
if (!this.list.Contains(key))
{
this.list.Add(key);
}
}
public void Clear()
{
this.dictionary.Clear();
this.list.Clear();
}
public bool Contains(KeyValuePair<K, V> item)
{
return this.dictionary.Contains(item);
}
public bool ContainsKey(K key)
{
return this.dictionary.ContainsKey(key);
}
public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(KeyValuePair<K, V> item)
{
if (this.Contains(item)){
this.list.Remove(item.Key);
return this.dictionary.Remove(item.Key);
} else
{
return false;
}
}
public bool Remove(K key)
{
if (this.dictionary.ContainsKey(key))
{
this.list.Remove(key);
return this.dictionary.Remove(key);
}
else
{
return false;
}
}
public bool TryGetValue(K key, [MaybeNullWhen(false)] out V value)
{
return this.dictionary.TryGetValue(key, out value);
}
public V Get(K key)
{
V value = default(V);
this.dictionary.TryGetValue(key, out value);
return value;
}
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
foreach (K key in this.list){
V value = default(V);
this.dictionary.TryGetValue(key, out value);
yield return new KeyValuePair<K, V>(key, value);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
private class LinkedDictionaryIterator<K, V> : IEnumerator<V>
{
private int i;
private readonly Dictionary<K, V> dictionary;
private readonly List<K> list;
public LinkedDictionaryIterator(Dictionary<K, V> dictionary, List<K> list)
{
this.dictionary = dictionary;
this.list = list;
this.i = 0;
}
public void Dispose()
{
}
public bool MoveNext()
{
return this.i < this.dictionary.Count;
}
public void Reset()
{
this.i = 0;
}
public KeyValuePair<K, V> Current
{
get
{
int ii = this.i;
++this.i;
V value = default(V);
K key = this.list[ii];
this.dictionary.TryGetValue(key, out value);
return new KeyValuePair<K, V>(key, value);
}
}
V IEnumerator<V>.Current
{
get
{
int ii = this.i;
++this.i;
V value = default(V);
K key = this.list[ii];
this.dictionary.TryGetValue(key, out value);
return value;
}
}
object IEnumerator.Current
{
get
{
return Current;
}
}
}
还有一个简单的单元测试,我将其与字典进行比较
class UnitTest_LinkedDictionary
{
[Test]
public void Test00()
{
LinkedDictionary<string, int> d = new LinkedDictionary<string, int>();
d.Add("1", 1);
d.Add("2", 2);
d.Add("3", 3);
d.Remove("2");
d.Add("4", 4);
d.Select(i => $"{i.Key}: {i.Value}").ToList().ForEach(Console.WriteLine);
}
[Test]
public void Test01()
{
Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("1", 1);
d.Add("2", 2);
d.Add("3", 3);
d.Remove("2");
d.Add("4", 4);
d.Select(i => $"{i.Key} :{i.Value}").ToList().ForEach(Console.WriteLine);
}
}
由于在C#中仍然没有LinkedHashMap,而我需要这个功能,在最新的net core(3.1)上实现了一个。https://github.com/idlerboris/LinkedHashMap/blob/master/CustomCollections/CustomCollections/LinkedHashMap.cs。它经过基本测试,看起来不错,但欢迎贡献/报告问题。