Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
132 views
in Technique[技术] by (71.8m points)

Scala: Problems creating generic collection

I have two sorted lists, and want to create an iterator which will merge the two lists in sorted oder. I'm new to Scala and especially new with writing generic classes. I get a compile error that I'm unable to figure out.

Here is the code for 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")
   }
 }
}

And here is the Unit Test, which is what doesn't compile:

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
  }

}

However when I try to compile, I get the following errors.

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)

I'm sure it's something stupid that I'm doing wrong, but due to my lack of experience with scala I've been able to figure out what the problem is. Any help here would be appreciated.

question from:https://stackoverflow.com/questions/65851046/scala-problems-creating-generic-collection

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to make

case class ComparableInt(value: Int) extends Ordered[ComparableInt] {
    override def compare(that: ComparableInt): Int = value.value - value.value
}

The issue is in [ElementType <: Ordered[ElementType]] type bounds - you see ElementType should be ordered to itself and your case ComparableInt implements Ordered[Int] and meaning ComparableInt is not Ordered to itself as MergingIterator signature expects.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...