使用以下代码产生以下内容:
List(a, b)
List()
List(a, b, b, c)
我想要的当然是这样的结果:
List(a)
List(b)
List(a, b, b, c)
我认为这是因为差异联合和交叉相对于“==”工作。 问题是“==” - 运算符是最终的,不能在“Test”类中重写。
我怎样才能达到预期的效果?
以下是使用过的代码:
package scalatest;
public class JStringHolder {
String s = null;
public JStringHolder(String newString){
s = newString;
}
@Override
public String toString() {
return s;
}
@Override
public boolean equals(Object obj) {
System.out.println("SHEQ " + this.s + " AND " + ((JStringHolder)obj).s + " " + this.s.equals(((JStringHolder)obj).s));
return this.s.equals(((JStringHolder)obj).s);
}
}
要执行的scala代码:
package scalatest
object ListTest {
trait AbstractTest
case class Test(stringHolder: scalatest.JStringHolder) extends AbstractTest {
override def toString = stringHolder.toString()
override def equals(ot: Any) : Boolean = {
return stringHolder.equals(ot.asInstanceOf[Test].stringHolder)
}
}
def main(args : Array[String]) : Unit = {
val l1 = List(Test(new JStringHolder("a")), Test(new JStringHolder("b")))
val l2 = List(Test(new JStringHolder("b")), Test(new JStringHolder("c")))
println (l1.diff(l2))
println (l1.intersect(l2))
println (l1.union(l2))
}
}
答案 0 :(得分:3)
问题是,你应该以某种方式覆盖hashCode方法,当你认为它们是相同的时,两个实例显示相同的hashCode。只有当hashCode相同时,才会调用equals方法,否则两个实例不一样(至少在List.diff意义上是相交的)。
使用下面的代码将达到我想要的结果:
List(a)
List(b)
List(a, b, b, c)
以下是使用过的代码:
package scalatest;
public class JStringHolder {
String s = null;
public JStringHolder(String newString){
s = newString;
}
@Override
public String toString() {
return s;
}
@Override
public boolean equals(Object obj) {
return this.s.equals(((JStringHolder)obj).s);
}
@Override
public int hashCode() {
return s.hashCode();
}
}
要执行的scala代码:
package scalatest
object ListTest {
trait AbstractTest
case class Test(stringHolder: scalatest.JStringHolder) extends AbstractTest {
override def toString = stringHolder.toString()
override def equals(ot: Any) : Boolean = {
return stringHolder.equals(ot.asInstanceOf[Test].stringHolder)
}
override def hashCode() : Int = {
stringHolder.hashCode()
}
}
def main(args : Array[String]) : Unit = {
val l1 = List(Test(new JStringHolder("a")), Test(new JStringHolder("b")))
val l2 = List(Test(new JStringHolder("b")), Test(new JStringHolder("c")))
println (l1.diff(l2))
println (l1.intersect(l2))
println (l1.union(l2))
}
}
答案 1 :(得分:1)
我不太确定:如果执行diff会出现错误?使用已弃用的--
代替diff
实际上对我有用。 Set
代替List
也可以。
我没有回答(只是建议使用Set作为解决方法)但我在这里添加自己的测试,以防他们可以帮助其他人回复:
// re-implementing JStringHolder in scala
// to show that this is not java-specific
class JStringHolder(val st: String) {
override def equals(that: Any): Boolean = that match {
case t: JStringHolder => this.st == t.st
case _ => false
}
}
case class Test(stringHolder: JStringHolder) {
override def equals(that: Any) : Boolean = that match {
case t: Test => this.stringHolder == t.stringHolder
case _ => false
}
}
现在在REPL(scala 2.9.0.1)中:
scala> List(Test(new JStringHolder("a")), Test(new JStringHolder("b")))
res0: List[Test] = List(a, b)
scala> List(Test(new JStringHolder("c")), Test(new JStringHolder("b")))
res1: List[Test] = List(c, b)
scala> res0 diff res1
res2: List[Test] = List(a, b)
- 已弃用,但有效
scala> res0 -- res1
<console>:13: warning: method -- in class List is deprecated: use `list1 filterN
ot (list2 contains)` instead
res0 -- res1
^
res3: List[Test] = List(a)
使用filterNot执行此操作(如弃用警告所示)也可以使用
scala> res0 filterNot (res1 contains )
res4: List[Test] = List(a)
此外,显示所有内容均适用于Set
scala> Set(Test(new JStringHolder("a")), Test(new JStringHolder("b")))
res0: scala.collection.immutable.Set[Test] = Set(a, b)
scala> Set(Test(new JStringHolder("b")), Test(new JStringHolder("c")))
res1: scala.collection.immutable.Set[Test] = Set(b, c)
scala> res0 diff res1
res2: scala.collection.immutable.Set[Test] = Set(a)
scala> res0 union res1
res3: scala.collection.immutable.Set[Test] = Set(a, b, c)
scala> res0 intersect res1
res4: scala.collection.immutable.Set[Test] = Set(b)
答案 2 :(得分:0)
除了使用合理的equals
方法将这些值封装在某些内容之外,您没有太多选择。
答案 3 :(得分:0)
scala> object ListTest {
|
| trait AbstractTest
| case class Test (stringHolder: JStringHolder) extends AbstractTest {
| override def toString = stringHolder.toString ()
| override def equals (ot: Any) : Boolean = {
| stringHolder.equals (ot.asInstanceOf [Test].stringHolder)
| }
| }
|
| def main (args : Array [String]) : Unit = {
| val a = Test (new JStringHolder ("a"))
| val b = Test (new JStringHolder ("b"))
| val c = Test (new JStringHolder ("c"))
| val l1 = List (a, b)
| val l2 = List (b, c)
| println (l1.diff (l2))
| println (l1.intersect (l2))
| println (l1.union (l2))
| }
| }
defined module ListTest
scala> ListTest.main (null)
List(a)
List(b)
List(a, b, b, c)
第一个测试(JStringHolder(&#34; b&#34;))不是==第二个。