我正在为我的自定义类实现等于运算符=
。该类有一个属性Value
,它本身是List(Of OtherClass)
,其中OtherClass
是我项目中的另一个自定义类。
我已经实施了IComparer
,IComparable
,IEqualityComparer
和IEquatable
接口,运营商=
,<>
,{ {1}}和bool
,并覆盖not
的{{1}}和Equals
。这应该给我比较这些对象所需的所有工具,以及迄今为止比较这些对象的两个单一实例的各种测试。
但是,当我们在GetHashCode
时,我不确定如何处理这个问题。我不关心列表顺序。给出:
OtherClass
然后List
应打印出Dim x As New List(Of OtherClass) From
{New OtherClass("foo"),
New OtherClass("bar"),
New OtherClass("baz")}
Dim y As New List(Of OtherClass) From
{New OtherClass("baz"),
New OtherClass("foo"),
New OtherClass("bar")}
。
我需要比较此列表中相同(不明显)的对象集。该列表不应该支持(x = y).ToString
的欺骗,但我必须弄清楚如何在以后作为例外添加它。对使用LINQ不感兴趣。它看起来不错,但在我玩过的几个例子中,增加了性能开销,这让我感到困扰。循环是丑陋的,但它们很快:)
直接的代码答案很好,但我也想了解这种比较所需的逻辑。我可能不得不在未来几次实施所述逻辑。
答案 0 :(得分:4)
您的示例应返回false。列表与LT;&GT;是有序集合,如果X包含foo,bar,baz,它与baz,foo,bar不同。你不应该改变这种预期的行为!你描述的是一个集合或包,而不是列表。袋子类似于列表,但不关心物品的顺序。那么在你的例子中它显然会返回true。
为清晰起见编辑:列出&lt;&gt;按项目索引排序,而不是按其值排序。这种收集的这一重要特性影响了它在所有操作中的行为和速度。
好的,忘了它,让我们说你只想按照你的定义进行测试。如果您对内容进行排序然后进行比较,最快的通用应用算法将为O(n * log2n)。 -1。您可以将两个列表排序为两个临时集合,然后只是比较它们的项目。 -2。您可以将X排序为临时集合,然后依次通过Y并尝试在X中查找Y的每个项目并将其删除。最后你可以看到temp是否为空,然后X和Y是相同的。 -3。如果您经常比较相等而不经常插入新项目,则可以创建一些新的“智能”列表,它将在插入时对项目进行排序。它将由一个真正的List&lt;&gt;组成。和里面的某种排序集合。
对复杂性的粗略分析:
选项1.和2.在插入n个项目时为O(n),在比较两个列表时为O(n * log2n)。
选项3.在插入n个项目时为O(n * log2n),在比较两个列表时为O(n)。
如果你想得到O(n * log2n),你可能需要去一个不同于List&lt;&gt;的集合。如果你使用类HashSet(从.NET 3.5开始),你可能会得到更快的结果。但我没有在实践中尝试过。 HashSet是无序集合aka set / bag的实现。它不支持比较两个哈希集,但你可以这样做:
使用foreach迭代X项,并尝试在Y中找到每个项目。
if(X.Count != Y.Count) return false;
foreach(var i in X) {
if(Y.Contains(i)==false) return false;
}
return true;
此代码在列表上非常慢,它是O(n ^ 2)。但它应该在HashSets上非常快,O(n)。如果你没有遇到任何隐藏的问题,这应该像火箭一样飞行!
在实践中,如果你需要留下List&lt;&gt;并且想要HashSet&lt;&gt;的速度,你可以只将你的一个集合(X或Y)重写为一个新的类,里面将包含两个集合 - 一个List&lt;&gt;和HashSet&lt;&gt; - 并将所有项目存储到他们两个。
您还可以使用经典词典&lt;&gt;,HashTable或其他一些经典的.NET集合来实现相同的功能。它们比比较两个Lits运行得更快,但可能需要更多内存而不是像HashSet一样快。
答案 1 :(得分:-1)
好的Al Kepp我的方法有问题,
For Each i In CompList1
Dim indexOfMyItem = CompList1.IndexOf(i)
If Not (CompList2.Contains(i) = False) Then
If Not test.ListBox1.Items.Contains(indexOfMyItem) Then
test.ListBox1.Items.Add(indexOfMyItem)
End If
End If
Next
我有两个列表例如:
CompList1: 0)香蕉 1)苹果 2)苹果 3)苹果 4)草莓 5)樱桃 6)樱桃 7)樱桃 8)猕猴桃
CompList2: 0)苹果 1)樱桃
我需要从list1中的每个匹配中获取索引并将其添加到列表中,由于某些原因我无法弄清楚,我只得到索引1和5,并且没有添加2 3 6 7。
有人能帮助我吗?
编辑:
好吧,这是我对.IndexOf()的误解 - 它只是找到列表中的第一项,其中包含()
中指定的文本因此我必须按照以下方式正常工作:
Dim indexOfMyItem As Integer = -1
For Each i In CompList1
indexOfMyItem = indexOfMyItem + 1
If CompList2.Contains(i) Then
If Not test.ListBox1.Items.Contains(indexOfMyItem) Then
test.ListBox1.Items.Add(indexOfMyItem)
End If
End If
Next