【发布时间】:2011-11-09 13:34:27
【问题描述】:
我有这种情况,其中内存保护是最重要的。我正在尝试将 > 1 GB 的肽序列读入内存并将共享相同序列的肽实例组合在一起。我将 Peptide 对象存储在 Hash 中,以便快速检查是否存在重复,但发现您无法访问 Set 中的对象,即使知道 Set 包含该对象也是如此。
内存真的很重要,如果可能的话,我不想复制数据。 (否则我会将我的数据结构设计为:peptides = Dictionary<string, Peptide> 但这会在字典和 Peptide 类中复制字符串)。以下是向您展示我想要完成的代码:
public SomeClass {
// Main Storage of all the Peptide instances, class provided below
private HashSet<Peptide> peptides = new HashSet<Peptide>();
public void SomeMethod(IEnumerable<string> files) {
foreach(string file in files) {
using(PeptideReader reader = new PeptideReader(file)) {
foreach(DataLine line in reader.ReadNextLine()) {
Peptide testPep = new Peptide(line.Sequence);
if(peptides.Contains(testPep)) {
// ** Problem Is Here **
// I want to get the Peptide object that is in HashSet
// so I can add the DataLine to it, I don't want use the
// testPep object (even though they are considered "equal")
peptides[testPep].Add(line); // I know this doesn't work
testPep.Add(line) // THIS IS NO GOOD, since it won't be saved in the HashSet which i use in other methods.
} else {
// The HashSet doesn't contain this peptide, so we can just add it
testPep.Add(line);
peptides.Add(testPep);
}
}
}
}
}
}
public Peptide : IEquatable<Peptide> {
public string Sequence {get;private set;}
private int hCode = 0;
public PsmList PSMs {get;set;}
public Peptide(string sequence) {
Sequence = sequence.Replace('I', 'L');
hCode = Sequence.GetHashCode();
}
public void Add(DataLine data) {
if(PSMs == null) {
PSMs = new PsmList();
}
PSMs.Add(data);
}
public override int GethashCode() {
return hCode;
}
public bool Equals(Peptide other) {
return Sequence.Equals(other.Sequence);
}
}
public PSMlist : List<DataLine> { // and some other stuff that is not important }
为什么HashSet 不让我获取包含在 HashSet 中的对象引用?我知道人们会说如果HashSet.Contains() 返回true,那么你的对象是等价的。它们在值方面可能是等价的,但我需要引用相同,因为我将附加信息存储在 Peptide 类中。
我想出的唯一解决方案是Dictionary<Peptide, Peptide>,其中键和值都指向同一个引用。但这似乎很俗气。是否有其他数据结构可以完成此任务?
【问题讨论】:
-
非常有趣,但也是 Why can't I retrieve an item from a HashSet without enumeration? 的副本@ +1 仍然是一个很好的问题。
-
当键也是值的属性时,扩展
KeyedCollection<TKey, TItem>是一个不错的选择。 -
我会在 Skeet 回复中添加一些内容:如果你想重新实现 HashSet,你可以从 mono 项目中获取并修改它:-) 你甚至可以尝试查看 C5 (itu.dk/research/c5 ) 看看有没有什么有用的。
标签: c# dictionary hashset