Scala map方法的行为不符合预期

时间:2012-04-22 16:52:18

标签: scala

我是Scala的新手,所以很可能这是一个非常明显的错误。但是,我正在尝试将List [Object]转换为List [A],其中A是类中的参数。

class AbstractHibernateDAO[A<:Serializable]{
  def findAll: List[A] = {
    val objList = currentSession.createQuery("from " + clazz.getName()).list()
    objList.map{_.asInstanceOf[A]}
  }
}
Eclipse正在努力:

type mismatch;  found   : ?0(in method findAll) => A where type ?0(in method findAll)  required: (some other)?0(in method findAll) => ? where type (some other)?0(in method findAll)    AbstractHibernateDAO.scala  /springHibernateNoXML/src/main/scala/my/package

我也试过长篇

objList.map{obj => obj.asInstanceOf[A]}

并获得相同的结果。

任何人都可以帮我一把吗?

[编辑 - 补充资料]

对于那些要求的人,这里是完整列表:

package name.me


import java.io.Serializable
import java.util.List
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.config.BeanDefinition
import org.springframework.context.annotation.Scope
import org.springframework.orm.hibernate3.HibernateTemplate
import org.springframework.stereotype.Repository
import com.google.common.base.Preconditions
import org.hibernate.SessionFactory
import org.hibernate.Session
import collection.JavaConversions._

@Repository
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
class AbstractHibernateDAO[A<:Serializable]{

  val clazz: Class[A] = null
  @Autowired val sessionFactory: SessionFactory = null

  def currentSession: Session = {
    sessionFactory getCurrentSession
  }

  def findOne(id: Long): A = {
    Preconditions checkArgument(id != null)
    currentSession.get(clazz, id).asInstanceOf[A]
  }

  def findAll: List[A] = {
    val objList = currentSession.createQuery("from " + clazz.getName()).list()
    objList.map(_.asInstanceOf[A])
    //This works
    //objList.asInstanceOf[List[A]]
  }

  def save(entity:A){
    Preconditions checkNotNull entity
    currentSession persist entity
  }

  def update(entity: A){
    Preconditions checkNotNull entity
    currentSession merge entity
  }

  def delete(entity: A){
    Preconditions checkNotNull entity
    currentSession delete entity
  }

  def deleteById(entityId: Long){
    Preconditions checkNotNull entityId
    val entity = findOne(entityId) 
    Preconditions checkNotNull entity
    delete(entity)
  }
}

2 个答案:

答案 0 :(得分:3)

您确定objList的类型吗?它真的是scala.collection.immutable.List java.util.Object吗?您可以通过在变量声明中添加类型来轻松检查:

val objList: List[java.util.Object] = ...

假设这是正确的,你的代码似乎没问题。但是如果没有其他所有代码,我就无法运行它。我可以用一个简单的例子做你正在尝试的事情:

def convertAll[A](data: List[java.lang.Object]): List[A] =
  data.map(_.asInstanceOf[A])

convertAll[java.lang.Integer](List(1,2).map(new java.lang.Integer(_)))
// List[java.lang.Integer] = List(1, 2)

但是,您不需要在List中投放每个项目。尝试将列表转换为新类型:

objList.asInstanceOf[List[A]]

例如:

val x: List[java.lang.Object] = List(1,2).map(new java.lang.Integer(_))
x.asInstanceOf[List[java.lang.Integer]]
// List[java.lang.Integer] = List(1, 2)

答案 1 :(得分:2)

快速查看Hibernate API docs表示Query.list()会返回java.util.List,但您的类型注释为List[A],默认情况下(来自scala.collection.immutable.List 3}})class AbstractHibernateDAO[A<:Serializable]{ def findAll: java.util.List[A] = { val objList = currentSession.createQuery("from " + clazz.getName()).list() objList.asInstanceOf[java.util.List[A]] } }

你想回来哪个?

对于Java List,更改类型注释并转换整个列表:

class AbstractHibernateDAO[A<:Serializable]{
  def findAll: List[A] = {
    val objList = currentSession.createQuery("from " + clazz.getName()).list()
    import collection.JavaConversions._
    objList.toList.asInstanceOf[List[A]]
  }
}

对于Scala List,请使用JavaConversions:

{{1}}