为什么最多 4 个元素的集合是有序的,而更大的元素则不是?

2024-04-16

Given

val xs1 = Set(3, 2, 1, 4, 5, 6, 7)
val ys1 = Set(7, 2, 1, 4, 5, 6, 3)

xs1 and ys1两者都导致scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 7, 3, 4)

但下面有较小的集合

val xt1 = Set(1, 2, 3)
val yt1 = Set(3, 2, 1)

produce

xt1: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
yt1: scala.collection.immutable.Set[Int] = Set(3, 2, 1)

为什么前者没有订购而后者似乎已订购?


行为差异是由于优化 https://github.com/scala/scala/blob/a3791d4d61bd584f27e4dac8765f753a27bb95e0/src/library/scala/collection/immutable/Set.scala#L188对于套最多 4 个元素 https://docs.scala-lang.org/overviews/collections-2.13/sets.html

不可变集的默认实现使用表示 适应集合的元素数量。空集是 仅由一个单例对象表示。套尺寸最多为四个是 由将所有元素存储为字段的单个对象表示。 超出该大小,不可变集的实现方式为压缩的 哈希数组映射前缀树 https://docs.scala-lang.org/overviews/collections-2.13/concrete-immutable-collection-classes.html#compressed-hash-array-mapped-prefix-trees.

类似地解释为本·詹姆斯 https://stackoverflow.com/a/7018941/5205022:

Set 也是一个带有 apply** 方法的伴随对象*。你打电话时 Set(...),您正在调用此工厂方法并获得返回 value 是某种 Set。它可能是一个 HashSet,但也可能是 其他一些实现。根据2,默认实现 对于不可变集,对于空集和集合有特殊的表示 大小最大为 4。大小为 5 及以上的不可变集和可变集均使用 哈希集。

由于尺寸为Set(3, 2, 1, 4, 5, 6, 7)大于4,则其具体实现为HashSet

Set(3, 2, 1, 4, 5, 6, 7).getClass
class scala.collection.immutable.HashSet

这确实not https://stackoverflow.com/a/5246204/5205022保证插入顺序。另一方面,具体落实Set(1, 2, 3)是专门的班级Set3 https://github.com/scala/scala/blob/a3791d4d61bd584f27e4dac8765f753a27bb95e0/src/library/scala/collection/immutable/Set.scala#L190

Set(1,2,3).getClass
class scala.collection.immutable.Set$Set3

它将三个元素存储在对应的三个中fields

final class Set3[A] private[collection] (elem1: A, elem2: A, elem3: A) extends AbstractSet[A] ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么最多 4 个元素的集合是有序的,而更大的元素则不是? 的相关文章

随机推荐

  • 如何使用 matplotlib 一起绘制训练和测试图

    我正在尝试将 y train y test 然后 y train pred y test pred 一起绘制在一张图中 我使用以下代码来执行此操作 plot plt plot y test plt plot y pred plt plot
  • Google VR 视频无法加载

    我正在使用谷歌网页版 VR 视图 https developers google com vr concepts vrview web加载 360 度视频 但是当我加载视频时 它说错误 渲染 视频加载错误 对象事件 这是控制台显示的内容 当
  • 动画受面板限制

    有点难以描述 但我会尽力 我有一个带有图像和标签的控件 它需要有 2 个状态 大 和 小 在 大 状态下 图像应位于控件顶部中心 标签应位于下方中心 就像带有图像和标签停靠在顶部的停靠栏一样 在 小 状态下 图像应该较小并且位于控件的左上角
  • 无法在 std::variant 中采用相同类型

    我正在使用 c 17 并且想编写这样的代码 include
  • Magento 1.7.0.0 上的 SOAP V2 url 是什么

    1 7 0 0 版本中访问 Magento SOAP V2 的 url 是否已更改 当我尝试访问 上的服务 时http www somedomain com api v2 soap wsdl 1 http www somedomain co
  • 从 Web 服务下载文件 - 在 ASP.NET 站点中

    我想使用网络服务将文件从网站推送到浏览器 我当前正在将文件读入 base64 字节数组 并从 Web 服务返回该文件 这个网络服务是从网站调用的 我一直在思考如何将其作为原始文件推送到浏览器 理想情况下 我想将字节数组读入内存流 然后如果可
  • 当超过两次下载正在进行时 HttpSendRequest 阻塞

    在我们的程序中 每次需要发出HTTP请求时都会创建一个新线程 并且可以有多个线程同时运行 我遇到的问题是 如果我已经有两个线程正在运行 它们在读取时循环InternetReadFile 打电话后HttpSendRequest 任何后续尝试调
  • pandas.to_json 以特定形式输出日期格式

    数据框中日期的原始形式是 Date 2018 09 17 12 83 12 92 12 38 12 65 12 65 1937329 0 2018 09 10 12 92 13 12 12 81 12 83 12 83 1150470 0
  • C++ boost enable_if问题

    我有什么办法可以简化以下陈述吗 可能 使用boost enable if 我有一个简单的类结构 Base基类 Derived1 Derived2继承自Base 我有以下代码 template
  • 嵌套启动 --watch 更改后不重新加载(嵌套启动 --watch 不工作)

    我安装了 Nest js 当我运行 npm run start dev 运行 start watch 时 一切正常并且出现绿色日志 问题是 当我更新代码中的某些内容时 nest 不再更新 并且卡在下图中 我确信这不是我的代码的问题 因为我在
  • Dojo 拖放:如何检索项目的顺序?

    我创建了一个 Source 对象并进行配置 通过创建者 以便它呈现一组数据供我的用户根据需要进行排序 这一切工作正常 但是 我无法弄清楚如何在用户重新排序后检索数据 getAllNodes 返回 dom 节点 我需要原始数据对象 这真的很简
  • java - 文件lastModified与读取文件

    我正在使用一个文件 并且需要在修改文件时更新 java 中的值 所以 我想使用检查修改时间lastModified of File类 如果修改 则读取文件并更新文件中的单个属性 我的疑问是 是lastModified与从文件中读取单个属性
  • 从 C# .net 调用 python.py

    我在从 C 调用 python 脚本时遇到问题 我的 python 脚本根据参数 1 和参数 2 计算一个值并发送计算出的值 我无法获得计算值 比如说 我正在使用一个简单的 python 类并调用 C 以下是 python py impor
  • C库函数获取活动线程数

    我正在用 C 语言开发一个多线程 Unix 应用程序 有没有一种简单的方法来获取同时活动线程的数量 如果库已经可以为我完成的话 我不想编写代码来跟踪活动线程的数量 我正在使用 POSIX pthreads 并且我正在尝试为 Unix 和类
  • 重命名字典中的键

    我想重命名字典的键是整数 并且我需要它们是带有前导零的整数 以便它们正确排序 例如我的钥匙是这样的 1 101 11 我需要它们是 001 101 011 这就是我现在正在做的事情 但我知道有更好的方法 tmpDict for oldKey
  • 如何在 ES6 中使用所有默认值解构选项参数?

    我将 ES6 功能与 babel 编译器一起使用 我有一个将选项对象作为参数的函数 function myFunction option1 true option2 whatever console log option1 option2
  • 如何在使用支持库时构建带有 ListView 的 AppWidget?

    我想在早期版本的 Android 上的 AppWidget 中使用 ListView 拉格纳的回答在这个问题中 https stackoverflow com questions 8846743 app widget with listvi
  • 如何删除供应商代码插入的回调?

    我正在使用的 gem 插入了一个我想删除的 after save 回调 在我看来 从数组中删除符号比用猴子补丁解决问题更干净 如何访问回调数组 class UserSession lt Authlogic Session Base Don
  • symfony 2 中相同的 url 需要多个角色

    这是我的 security yml 的访问控制列表的样子 access control path admin roles IS AUTHENTICATED FULLY path admin roles ROLE ADMIN 我想要做的是 用
  • 为什么最多 4 个元素的集合是有序的,而更大的元素则不是?

    Given val xs1 Set 3 2 1 4 5 6 7 val ys1 Set 7 2 1 4 5 6 3 xs1 and ys1两者都导致scala collection immutable Set Int Set 5 1 6 2