Scala:创建通用集合的问题
Scala: Problems creating generic collection
我有两个排序列表,我想创建一个迭代器,它将两个列表按排序顺序合并。我是 Scala 的新手,尤其是编写通用 类 的新手。我遇到无法弄清楚的编译错误。
这是 MergingIterator
的代码
class MergingIterator[ElementType <: Ordered[ElementType]] (iterator1: BufferedIterator[ElementType], iterator2: BufferedIterator[ElementType]) extends Iterator[ElementType]{
override def hasNext: Boolean = {
iterator1.hasNext || iterator2.hasNext
}
override def next(): ElementType = {
if(!iterator1.hasNext && !iterator2.hasNext){
throw new IllegalStateException("All iterators empty. No next element")
}
val e1 : Option[ElementType] = if(iterator1.hasNext) Some(iterator1.head) else None
val e2 : Option[ElementType] = if(iterator2.hasNext) Some(iterator2.head) else None
if(e1.isDefined && e2.isDefined){
val e1a = e1.get
val e2a = e2.get
if(e1a.equals(e2a) || e1a < e2a){
iterator1.next()
}
else {
iterator2.next()
}
}
else if (e1.isDefined){
iterator1.next
}
else if (e2.isDefined){
iterator2.next()
}
else{
throw new Exception("InvalidState. No elements present")
}
}
}
这是无法编译的单元测试:
class MergingIteratorTest extends AnyFunSuite {
test("Both Iterators Empty"){
runTest(List(), List(), List())
}
private def runTest(vals1 : List[ComparableInt], vals2: List[ComparableInt], expected: List[ComparableInt]): Unit ={
val it1 = vals1.iterator.buffered
val it2 = vals2.iterator.buffered
val merging = new MergingIterator[ComparableInt](it1, it2)
val merged = merging.toList
assert(expected.equals(merged))
}
case class ComparableInt(value: Int) extends Ordered[Int] {
override def compare(that: Int): Int = value - that
}
}
然而,当我尝试编译时,出现以下错误。
Error:(14, 9) type arguments [MergingIteratorTest.this.ComparableInt] do not conform to class MergingIterator's type parameter bounds [ElementType <: Ordered[ElementType]]
val merging = new MergingIterator[ComparableInt](it1, it2)
Error:(14, 23) type arguments [MergingIteratorTest.this.ComparableInt] do not conform to class MergingIterator's type parameter bounds [ElementType <: Ordered[ElementType]]
val merging = new MergingIterator[ComparableInt](it1, it2)
我确定我做错了一些愚蠢的事情,但由于我缺乏使用 scala 的经验,我已经能够找出问题所在。如有任何帮助,我们将不胜感激。
你需要
case class ComparableInt(value: Int) extends Ordered[ComparableInt] {
override def compare(that: ComparableInt): Int = value.value - value.value
}
问题出在 [ElementType <: Ordered[ElementType]]
类型范围内 - 你会看到 ElementType
应该被排序到它自己,你的案例 ComparableInt
实现 Ordered[Int]
并且意味着 ComparableInt
不像 MergingIterator
签名期望的那样 Ordered
本身。
与 Ordering
类型 class 相同。
class MergedIterator[ElmTyp:Ordering](itrA: Iterator[ElmTyp]
,itrB: Iterator[ElmTyp]
) extends Iterator[ElmTyp] {
import Ordering.Implicits._
private val itr1 = itrA.buffered
private val itr2 = itrB.buffered
override def hasNext: Boolean = itr1.hasNext || itr2.hasNext
override def next(): ElmTyp =
if (!itr1.hasNext) itr2.next()
else if (!itr2.hasNext) itr1.next()
else if (itr1.head > itr2.head) itr2.next()
else itr1.next()
}
我有两个排序列表,我想创建一个迭代器,它将两个列表按排序顺序合并。我是 Scala 的新手,尤其是编写通用 类 的新手。我遇到无法弄清楚的编译错误。
这是 MergingIterator
的代码class MergingIterator[ElementType <: Ordered[ElementType]] (iterator1: BufferedIterator[ElementType], iterator2: BufferedIterator[ElementType]) extends Iterator[ElementType]{
override def hasNext: Boolean = {
iterator1.hasNext || iterator2.hasNext
}
override def next(): ElementType = {
if(!iterator1.hasNext && !iterator2.hasNext){
throw new IllegalStateException("All iterators empty. No next element")
}
val e1 : Option[ElementType] = if(iterator1.hasNext) Some(iterator1.head) else None
val e2 : Option[ElementType] = if(iterator2.hasNext) Some(iterator2.head) else None
if(e1.isDefined && e2.isDefined){
val e1a = e1.get
val e2a = e2.get
if(e1a.equals(e2a) || e1a < e2a){
iterator1.next()
}
else {
iterator2.next()
}
}
else if (e1.isDefined){
iterator1.next
}
else if (e2.isDefined){
iterator2.next()
}
else{
throw new Exception("InvalidState. No elements present")
}
}
}
这是无法编译的单元测试:
class MergingIteratorTest extends AnyFunSuite {
test("Both Iterators Empty"){
runTest(List(), List(), List())
}
private def runTest(vals1 : List[ComparableInt], vals2: List[ComparableInt], expected: List[ComparableInt]): Unit ={
val it1 = vals1.iterator.buffered
val it2 = vals2.iterator.buffered
val merging = new MergingIterator[ComparableInt](it1, it2)
val merged = merging.toList
assert(expected.equals(merged))
}
case class ComparableInt(value: Int) extends Ordered[Int] {
override def compare(that: Int): Int = value - that
}
}
然而,当我尝试编译时,出现以下错误。
Error:(14, 9) type arguments [MergingIteratorTest.this.ComparableInt] do not conform to class MergingIterator's type parameter bounds [ElementType <: Ordered[ElementType]]
val merging = new MergingIterator[ComparableInt](it1, it2)
Error:(14, 23) type arguments [MergingIteratorTest.this.ComparableInt] do not conform to class MergingIterator's type parameter bounds [ElementType <: Ordered[ElementType]]
val merging = new MergingIterator[ComparableInt](it1, it2)
我确定我做错了一些愚蠢的事情,但由于我缺乏使用 scala 的经验,我已经能够找出问题所在。如有任何帮助,我们将不胜感激。
你需要
case class ComparableInt(value: Int) extends Ordered[ComparableInt] {
override def compare(that: ComparableInt): Int = value.value - value.value
}
问题出在 [ElementType <: Ordered[ElementType]]
类型范围内 - 你会看到 ElementType
应该被排序到它自己,你的案例 ComparableInt
实现 Ordered[Int]
并且意味着 ComparableInt
不像 MergingIterator
签名期望的那样 Ordered
本身。
与 Ordering
类型 class 相同。
class MergedIterator[ElmTyp:Ordering](itrA: Iterator[ElmTyp]
,itrB: Iterator[ElmTyp]
) extends Iterator[ElmTyp] {
import Ordering.Implicits._
private val itr1 = itrA.buffered
private val itr2 = itrB.buffered
override def hasNext: Boolean = itr1.hasNext || itr2.hasNext
override def next(): ElmTyp =
if (!itr1.hasNext) itr2.next()
else if (!itr2.hasNext) itr1.next()
else if (itr1.head > itr2.head) itr2.next()
else itr1.next()
}