Scala转换器将Java集合转换为Wrapper对象

前端之家收集整理的这篇文章主要介绍了Scala转换器将Java集合转换为Wrapper对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个 scala函数,它返回一个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

未评估的内容也会更改为Wrapper $SetWrapper.是因为我试图将不可变的scala集合转换为java集合吗?我知道只有可变的scala集合兼容才能使用JavaConverters转换为相应的java集合

解决方法

JavaConverters将容器转换为java“就地”,而不复制数据.也就是说,如果你有一个scala Map,并将其转换为java,它就不会创建一个全新的容器,并将所有数据复制到它.相反,它只返回一个包装类,它实现了java的Map接口,但是由原始数据而不是副本支持.

这是一件好事,因为它可以节省内存和时间.

接口的整个概念是用户不应该关心它背后的特定实现. “编码到界面”是这个想法.找到自己关心实际的实现类通常(并不总是,但经常)是一种糟糕的设计气味.

如果必须将数据复制到容器中,这是特定类的实例,则必须明确地执行此操作:

val javaMap = new HashMap[String,Set[String]](wrappedMap)

更好的是,首先考虑不使用java序列化.它很慢,越野车,乏味,危险……并且迫使你像这样跳过数百万个奇怪的箍.现在有很多更好的选择.

猜你在找的Scala相关文章