How to concatenate a list to another list in scala

866 views Asked by At

Here i use to concatenate 2 Lists (with same type) using this :+

and the code is testResult :+ studentsearch

the length of the list get value zero in the console

Controller

@RequestMapping(value = Array("parent/ViewReports.html"))
 def viewReportPage(test: Test): String = {    

    var userAccount: UserAccount = secService.getLoggedUserAccount
    var z = userAccount.getId().toLong
    var studentsearch: java.util.List[StudentTest] = Nil
    var studentTestResult: java.util.List[StudentTest] =Nil
    var testResult: java.util.List[StudentTest] =Nil      

    var searchstudent = parentStudentService.findParentStudentByParent(z)

    for(srchStd <- searchstudent){    
      var sid= srchStd.getStudent().getId()  
      studentsearch = studentTestService.findAllStudentTestByStudent(sid)
    }

    testResult :+ studentsearch 
    println("Length:" +testResult.length)  
    studentTestResult = ListBuffer(testResult: _*)    .
    results = studentTestResult

    "redirect:/parent/result.html"
}

the concatenate code is wrong ?

please share your answers

4

There are 4 answers

0
tmbo On BEST ANSWER

Your code uses scala constructs in an interesting way. Which might not lead to correct results. The for comprehension in

for(srchStd <- searchstudent){    
  var sid= srchStd.getStudent().getId()  
  studentsearch = studentTestService.findAllStudentTestByStudent(sid)
}

reassigns studentsearch in each iteration to a new value, so in the end it is set to the value of the last iteration. If you want to accumulate the results something like

import scala.collection.JavaConversions._

val searchstudent = parentStudentService.findParentStudentByParent(z)

val testResult = searchstudent.flatMap{ srchStd =>
  val sid = srchStd.getStudent().getId()  
  studentTestService.findAllStudentTestByStudent(sid)
}

will result in all tests collected in testResult.

The import of scala.collection.JavaConversions._ helps converting between scala and java collections. More information can be found here: http://www.scala-lang.org/api/current/index.html#scala.collection.JavaConversions$.

6
Chris Martin On

You should look at the API docs for the :+ methods you're calling.

I'm not sure which Scala collection type that java.util.List is being implicitly converted to, but I think the :+ method is the same everywhere: http://www.scala-lang.org/api/current/#scala.collection.Seq

java.util.List is implicitly converted to scala.collection.mutable.Buffer.

A copy of this sequence with an element appended.

In other words, :+ doesn't modify the collection, so the statement TestResult :+ studentsearch has no effect.

You could call the Java collection's method directly: TestResult addAll studentsearch.

Although, may I ask, why are you using java.util.List instead of a Scala collection?

I should also note, of course, that in Scala just like in Java, starting a variable name with a capital letter is frowned upon heavily. (testResult, not TestResult). It's even more important in Scala because variables and types share the same namespace, unlike in Java.

0
Robin Green On

For completeness, the operator used to concatenate a list to another list is ++=. Although as the accepted answer notes, it is better to use flatMap in this case. (You can also use for..yield.)

0
Jonny Coombes On

You may want to look at the JavaConversions object within the Scala standard library, which allows you to migrate between Scala types and Java collections. Which from the documentation supports the following conversions:

scala.collection.Iterable <=> java.lang.Iterable
scala.collection.Iterable <=> java.util.Collection
scala.collection.Iterator <=> java.util.{ Iterator, Enumeration }
scala.collection.mutable.Buffer <=> java.util.List
scala.collection.mutable.Set <=> java.util.Set
scala.collection.mutable.Map <=> java.util.{ Map, Dictionary }
scala.collection.mutable.ConcurrentMap (deprecated since 2.10) <=> java.util.concurrent.ConcurrentMap
scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap

You should probably also consider using native Scala collections (List, Seq etc...) in situations where the collections are being created/populated natively within Scala and not being generated through an outcall to an existing lump of Java code.

Hope this helps