加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 声明类型不同时的不同行为(Set vs TreeSet)

发布时间:2020-12-16 09:08:59 所属栏目:安全 来源:网络整理
导读:var set = TreeSet(5,4,3,2,1) println(set) val diffSet: TreeSet[Int] = set // if I change above code to val diffSet: Set[Int] = set // the result is unsorted set. for (i - diffSet; x = i) { println(i) } println("-" * 20) // the above code t
var set = TreeSet(5,4,3,2,1)
    println(set)

    val diffSet: TreeSet[Int] = set
    // if I change above code to val diffSet: Set[Int] = set
    // the result is unsorted set.

    for (i <- diffSet; x = i) {
        println(i)
    }
    println("-" * 20)
    // the above code translates to below and print the same result
    val temp = diffSet.map(i => (i,i))
    for ((i,x) <- temp) {
        println(i)
    }

我的问题是,如果我定义了这样的方法:

def genSet:Set[Int] = {
  TreeSet(5,1)
}

当我想使用for循环时

for (i <- genSet; x = i + 1) {
  println(x)
}

结果是未排序的,如何在不更改genSet的返回类型的情况下修复此行为.如果我像下面这样使用循环,它会很好,但我希望保持上面的代码风格.

for (i <- genSet) {
  val x = i + 1
  println(x)
}

解决方法

为什么地图版本没有排序

map方法(使用我们称之为func的函数调用)采用隐式CanBuildFrom参数,该参数除了func返回以选择适当的返回类型的类型之外,还考虑了要调用映射的集合的类型. .这用于使Map.map [Int]或BitSet.map [String]做正确的事情(返回通用列表),而Map.map [(String,Int)]或BitSet.map [Int]也做正确的事情thing(分别返回Map和BitSet).

CanBuildFrom是在编译时选择的,因此必须根据您调用map的集合的静态类型(编译时编译器知道的类型)来选择它.静态类型的集合是TreeSet,但是diffset的静态类型是Set.两者的动态类型(在运行时)是TreeSet.

当您在set(TreeSet)上调用map时,编译器选择immutable.this.SortedSet.canBuildFrom [Int](math.this.Ordering.Int)作为CanBuildFrom.

当你在diffset(一个Set)上调用map时,编译器选择immutable.this.Set.canBuildFrom [Int]作为CanBuildFrom.

为什么版本结束未分类

循环

for (i <- genSet; x = i + 1) {
  println(x)
}

desugars into

genSet.map(((i) => {
              val x = i.$plus(1);
              scala.Tuple2(i,x)
            })).foreach(((x$1) => x$1: @scala.unchecked match {
              case scala.Tuple2((i @ _),(x @ _)) => println(x)
            }))

desugared版本包括一个map函数,它将使用未经排序的CanBuildFrom,如上所述.

另一方面,循环

for (i <- genSet) {
  val x = i + 1
  println(x)
}

desugars into

genSet.foreach(((i) => {
              val x = i.$plus(1);
              println(x)
            }))

它根本不使用CanBuildFrom,因为没有返回新的集合.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读