Realm collection是包含零个或多个某一类型实例的对象。Realm collection是同质的,即collection中的所有对象都是同一类型。
您可以使用 Realm 的查询引擎对任意集合进行筛选和排序。集合为实时对象,因此它们始终会反映当前线程上 Realm 实例的当前状态。此外,还可通过订阅集合通知来侦听集合中的更改。
Realm 有两种collection:列表和结果。
列表
Realm 对象可以包含非 Realm 对象数据类型的列表。 您可以使用类型 RealmList<T>对这些collection进行建模,其中T可以是以下类型:
StringIntegerUUIDObjectIdBooleanFloatDoubleShortLongBytebyte[]Date
提示
listCollections
collection表示两个 Realm 类型之间的关系。列表是可变的:在写事务(write transaction)中,您可以添加和删除列表上的元素。列表不与查询关联。
结果集合
结果集合表示查询操作的延迟计算结果。 结果不可变:您无法在结果collection上添加或删除元素。结果具有确定其内容的关联查询。
RealmResults 类继承自 AbstractList ,且行为方式类似。示例,RealmResults 是有序的,您可以通过索引访问权限各个对象。如果查询没有匹配项,则返回的RealmResults 对象将是长度为0 的列表,而不是null 对象引用。
您只能在写事务(write transaction)中修改或删除RealmResults集中的对象。
迭代
由于 Realm collection 是实时的,因此当您迭代 collection 时,对象可能会移动。您可以使用快照安全地迭代集合。
适配器
Realm 提供了适配器来帮助将数据绑定到标准 UI 小部件。 这些类可与任何实现OrderedRealmCollection接口的类一起使用,其中包括内置的RealmResults和RealmList类。 有关适配器的更多信息,请参阅有关显示collection的文档。
重要
适配器需要托管对象
The Realm adapters only accept managed Realm object instances tied to an instance of a realm. 要显示非托管对象,请对回收器视图使用通用的 Android RecyclerView.Adapter ,或对列表视图使用ArrayAdapter 。
集合的实时性
与活动对象一样,Realm 集合通常也为实时集合:
实时结果集合始终会反映关联查询的当前结果。
实时列表始终会反映 Realm 实例关系的当前状态。
collection在三种情情况下处于非实时状态:
该集合为非托管集合,例如尚未添加到 Realm 或已从 Realm 复制的 Realm 对象的 List 属性。
集合已被冻结。
collection是快照的一部分。
与集合通知相结合时,实时集合可实现简洁的响应式代码。例如,假设您的视图会显示查询结果。您可在视图类中保留对结果集合的引用,然后按需读取结果集合,而不必刷新该集合或验证其是否处于最新状态。
警告
索引可能会更改
结果会自动更新。 如果存储集合中对象的位置索引或集合中对象的计数,则存储的索引或计数值在您使用时可能已过时。
结果为延迟计算出的结果
Realm 仅在您实际请求该查询的结果时才会运行查询,例如通过访问结果集合的元素。此延迟求值机制可让您编写优雅、高性能的代码来处理大型数据集和复杂查询。
限制查询结果
由于出现延迟求值,因此无需任何特殊机制来限制 Realm 的查询结果。例如,如果您的查询匹配到数千个对象,但您只想加载前十个对象,则只需访问结果集合的前十个元素即可。
分页
借助延迟求值,分页的常见任务变得非常简单。例如,假设您有一个与某一查询关联的结果集合,而该查询可与您 Realm 中的数千个对象匹配。您选择每页显示一百个对象。要前进到任一页面,只需从与目标页面相对应的索引开始访问结果集合中的元素即可。
列表与结果
当您需要集合时,您可以使用以下经验规则来确定列表和结果集合是否合适:
定义 Realm 对象的属性时,请使用列表定义除 隐式反向关系 之外 的一对多 关系。
在其他地方使用结果。
要了解这些不同的使用案例,请考虑是否应该能够直接添加或删除对象。 列表允许您直接添加和删除对象,因为您可以控制关系。 结果collection不允许直接添加或删除对象,因为它们的内容由查询确定。
例子
考虑名为 Person 的 Realm 类型,其中包含名为emails的字段,该字段是表示电子邮件地址的 collection。您可以控制这些数据。 您的应用程序需要在 Person 实例中添加和删除电子邮件地址。 因此,使用列表来定义emails的字段类型。
另一方面,当您在域中查询年龄超过 25 岁的所有 Person 时,直接在结果collection中添加或删除 Person 是没有意义的。仅当查询匹配到一组不同的人员时,该collection的内容才会更改。因此,Realm 会为您提供一个collection。