磁盘支持的阵列列表

有时,您的列表可能会变得太大而无法容纳在内存中,因此您必须采取一些措施以避免内存不足。

做到这一点的正确方法是流传输–而不是将所有内容都放入内存中,您应该从源流传输数据并丢弃已经处理的条目。

但是,在某些情况下,您无法控制的代码需要一个List而您不能使用流式传输。 这些情况很少见,但万一击中它们,您必须找到解决方法。 一种是重新实现代码以与流一起使用,但是根据编写库的方式,可能无法实现。 因此,另一种选择是使用磁盘支持的列表–一个用作列表的列表,但在其下方存储和加载磁盘中的元素。

搜索现有的解决方案会产生3年以上的仓库,例如这个这个这个

然后是MapDB ,它很棒并且受支持。 它主要是关于地图的,但是它也支持List,如此处所示

最后,如果您只需要迭代而几乎不需要别的,则可以选择自己实现一些简单的事情。 我在这里做了– DiskBackedArrayList.java 。 它不支持很多东西(并非所有方法都被重写以引发异常,但是应该)。 但最重要的是,它不支持随机添加和随机获取,也不支持toArray()。 它纯粹是“填充收藏集”,然后“迭代收藏集”。 它依赖于ObjectOutputStream ,效率不是很高,但是易于使用。 请注意,在需要将少量数据添加到列表的情况下,我允许使用较短的内存prependList。

该列表将填充到内存中,直到达到指定的阈值,然后刷新到磁盘,清除内存,内存又开始被填充。 这也可能会更有效–在另一个线程中进行后台刷新,这不会干扰将元素添加到列表中,但是优化使事情变得复杂,在这种情况下,总运行时间不是问题。 最重要的是,重写iterator()方法以返回一个自定义迭代器,该迭代器首先流式传输前置列表,然后从磁盘读取所有内容,最后遍历仍在内存中的最新批处理。 最后,最后应调用clear()方法以关闭基础流。 可以在每次刷新时打开和关闭输出流,但是由于某些特定于首先写入标头的实现,因此不能在附加模式下使用ObjectOutputStream

因此,基本上,我们将流方法隐藏在List接口的下面–它仍在流元素并在不需要时将其丢弃。 理想情况下,应在数据源(例如数据库,消息队列等)上完成此操作,而不是将磁盘用作溢出空间,但是在某些情况下,使用磁盘很好。 此实现是一个起点,因为尚未在生产中进行测试,但是说明您可以根据需要使现有类适应不同的数据访问模式。

翻译自: https://www.javacodegeeks.com/2019/12/a-disk-backed-arraylist.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值