Scala 转换器将 Java 个集合转换为 Wrapper 对象
Scala converters convert Java collections to Wrapper objects
我有一个 scala 函数,它 returns 一个 util.Map[String], util.Set[String]
。
def getAcls(): Map[String, Set[String]] = {
((for (groupRole: GroupRoleAccess <- groupRoleAccess;
user <- groupService.getGroup(groupRole.groupId).getUsers;
permissions = roleService.getRole(groupRole.roleId) .getPermissions)
yield user.getUserId -> permissions).groupBy(_._1).map { case (k,v) => (k, v.flatMap(_._2).asJava)})
}
我只是在一组这些对象上调用此方法以获得 util.Set[util.Map[String], util.Set[String]]
。
var unevaluatedacls = for (aclTemplate <- aclTemplates)
yield aclTemplate.getAcls
当我检查 unevaluatedacls
时,我发现它是 HashSet
类型。但是它的元素是 Wrappers$MapWrapper
类型而不是 util.Map
类型。因此,我无法保留该对象。我无法理解这种行为。当我尝试
var unevaluatedacls = (for (aclTemplate <- aclTemplates)
yield aclTemplate.getAcls).asJava
unevaluatedacls
也变为Wrapper$SetWrapper
。是因为我以某种方式试图将不可变的 Scala 集合转换为 java 集合吗?我知道只有可变的 Scala 集合才兼容,可以使用 JavaConverters
转换为相应的 java 集合
JavaConverters
转换容器 to/from java "in place",而不复制数据。也就是说,如果您有一个 scala Map
,并将其转换为 java,它不会创建一个全新的容器,也不会将所有数据复制到其中。相反,它只是 returns 一个包装器 class,它实现了 java 的 Map
接口,但由原始数据而不是副本支持。
这是一件好事,因为它节省了内存和时间。
接口的全部思想是用户不应该关心它背后的特定实现。 "Coding to interface" 就是这个主意。发现自己关心实际实现 classes 通常(不总是,但经常)是糟糕设计的味道。
如果您必须将数据复制到容器中,那是特定 class 的一个实例,您必须明确地执行此操作:
val javaMap = new HashMap[String, Set[String]](wrappedMap)
更好的是,首先考虑不使用 java 序列化。它缓慢、有故障、乏味、危险……并迫使你像这样跳过数百万个奇怪的圈套。现在有很多更好的选择。
我有一个 scala 函数,它 returns 一个 util.Map[String], util.Set[String]
。
def getAcls(): Map[String, Set[String]] = {
((for (groupRole: GroupRoleAccess <- groupRoleAccess;
user <- groupService.getGroup(groupRole.groupId).getUsers;
permissions = roleService.getRole(groupRole.roleId) .getPermissions)
yield user.getUserId -> permissions).groupBy(_._1).map { case (k,v) => (k, v.flatMap(_._2).asJava)})
}
我只是在一组这些对象上调用此方法以获得 util.Set[util.Map[String], util.Set[String]]
。
var unevaluatedacls = for (aclTemplate <- aclTemplates)
yield aclTemplate.getAcls
当我检查 unevaluatedacls
时,我发现它是 HashSet
类型。但是它的元素是 Wrappers$MapWrapper
类型而不是 util.Map
类型。因此,我无法保留该对象。我无法理解这种行为。当我尝试
var unevaluatedacls = (for (aclTemplate <- aclTemplates)
yield aclTemplate.getAcls).asJava
unevaluatedacls
也变为Wrapper$SetWrapper
。是因为我以某种方式试图将不可变的 Scala 集合转换为 java 集合吗?我知道只有可变的 Scala 集合才兼容,可以使用 JavaConverters
JavaConverters
转换容器 to/from java "in place",而不复制数据。也就是说,如果您有一个 scala Map
,并将其转换为 java,它不会创建一个全新的容器,也不会将所有数据复制到其中。相反,它只是 returns 一个包装器 class,它实现了 java 的 Map
接口,但由原始数据而不是副本支持。
这是一件好事,因为它节省了内存和时间。
接口的全部思想是用户不应该关心它背后的特定实现。 "Coding to interface" 就是这个主意。发现自己关心实际实现 classes 通常(不总是,但经常)是糟糕设计的味道。
如果您必须将数据复制到容器中,那是特定 class 的一个实例,您必须明确地执行此操作:
val javaMap = new HashMap[String, Set[String]](wrappedMap)
更好的是,首先考虑不使用 java 序列化。它缓慢、有故障、乏味、危险……并迫使你像这样跳过数百万个奇怪的圈套。现在有很多更好的选择。