【问题标题】:Limit Realm results限制领域结果
【发布时间】:2015-04-24 16:18:17
【问题描述】:

如何限制 Realm 返回的对象数量? .findAll 返回与查询匹配的所有行,而 .findFirst 仅返回第一行。但是像前 1000 个这样的东西呢? .findAll 可能会返回太多行,以至于消耗太多内存。

【问题讨论】:

    标签: android realm


    【解决方案1】:

    很酷的是,您无需担心 Realm。当您访问对象及其字段时,查询返回的结果对象会延迟加载它们。您的对象永远不会被复制,因此只会在内存/磁盘中表示一次。

    这个(当前的)实现细节是从查询返回的 RealmResults 对象只是对匹配对象的引用列表。这些引用是很小的数字,它们被压缩存储,因此它们占用的内存很少。因此,即使有 100.000 个匹配项,它实际上也不会占用太多内存。对于所有类型的对象,它会占用相同数量的内存,无论它们有一个 int 字段还是数百个带有字符串或大二进制文件的字段。

    【讨论】:

    • 如果使用 copyFromRealm 方法将领域结果存储到 List 会怎样?
    • 然后,您将复制所有对象,它们将占用普通 Java 对象所占用的全部内存量。因此,如果您有很多结果,那将是一个非常糟糕的主意。你总是希望避免复制我们的 Realm 对象,除非你必须这样做。然后通过网络发送。
    • 当我们存储到 realmResult.因为我在一列中有大量数据,但我在 recyclerview 中显示了一些来自领域结果 pojo 的小尺寸值。
    • 不,没有。但正如答案 realmResult 中解释的那样,它本身并不复制数据,它只保存底层数据中对象“行”的索引,因此 realmResult 使用的内存与您拥有多少数据和多少列无关。
    【解决方案2】:

    在使用官方文档https://realm.io/docs/java/latest中的“between”查询这么多天后,我找到了实现这一目标的解决方案

    如果要获取前 N 个元素,只需将计数从和到传递,字段名称如下

    realm.where(clazz).between("count",0,1000).findAll();
    

    在哪里,

    "count" = 字段名(即你的 pojo 中的变量名)
    "0" = Range From
    "1000" = 到

    的范围

    例如:上面的查询将获取第一个 0 到 1000 作为 RealmResults。

    注意:上述解决方案仅在您有一些具有行数的唯一 id 时才有效。就我而言,我在将值插入 Realm 之前手动插入了行计数值。

    【讨论】:

      【解决方案3】:

      如果你真的只想要RealmResults,可以使用Stream limit 方法:

      //get all results of your choice query
      RealmResults<TypeClass> entities = realm.where(TypeClass.class).findAll();
      //limit using Stream
      List<Integer> ids = Stream.of(entities).limit(10).map(x -> x.Id).collect(Collectors.toList());
      //return only those ids elments
      return realm.where(TypeClass.class).in("Id", ids.toArray(new Integer[])).findAll();
      

      【讨论】:

      • 不要忘记在 `entities`s RealmChangeListener 中重新计算这些
      【解决方案4】:

      Realm 目前不提供任何限制功能,但如果你想要前 N 个元素

      int N=10;   // whatever value you want
      Realm mRealm=Realm.getDefaultInstance();
      
      RealmResults<Example> list= mRealm.where(Example.class).findAll();
      list.subList(0,N);
      

      最后N个元素

      RealmResults<Example> list= mRealm.where(Example.class).findAll();
      list.subList(list.size()-N,list.size());
      

      【讨论】: