前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >List subList()方法缺陷及替代方案

List subList()方法缺陷及替代方案

作者头像
关忆北.
发布2023-10-11 09:35:49
4720
发布2023-10-11 09:35:49
举报
文章被收录于专栏:关忆北.
技术背景

在日常开发中,我们常遇到将一个List列表分割成多个的场景,List提供了subList()方法避免开发者重复造轮子。

subList()的用法

ArrayList类是接口List的一个实现,以下subList()使用方法参考示例来自ArrayList

代码语言:javascript
复制
		List<String> arrayList = new ArrayList<>();
		arrayList.add("hello");
		arrayList.add("hello1");
		arrayList.add("hello2");
		arrayList.add("hello3");
		List<String> subString = arrayList.subList(0, 1);
		System.out.println(subString);

输出: [hello]

subList实现

ArrayListsubList()源码如下:

代码语言:javascript
复制
public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, offset, fromIndex, toIndex);
}

SubList类是ArrayList的一个内部类,它继承自AbstractList抽象类,在SubList的构造方法中,入参有原始list的引用,SubList类的get方法源码如下:

代码语言:javascript
复制
//ArrayList的原始数组 
transient Object[] elementData; 


@SuppressWarnings("unchecked")
E elementData(int index) {
    return (E) elementData[index];
}

/**
 * Returns the element at the specified position in this list.
 *
 * @param  index index of the element to return
 * @return the element at the specified position in this list
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

可以看到,SubListget()方法是通过下标来获取原数组的数据,而不是返回一个新的对象,当代码中有对分割后的列表访问时,便是对原ArrayList的引用,导致该对象不会被GC回收,数据量大时,有导致OOM的风险。因此,我们需要找到新的方案去解决代码中的风险点。

解决方案

使用Stream的方式分割。

通过skip()方法获取某个元素节点之后的数据
代码语言:javascript
复制
//获取第2个节点后的数据(包含第2个元素)
List<String> skipList = arrayList.stream().skip(1).collect(Collectors.toList());

输出: [hello2, hello3]

通过limit()方法获取某个元素节点之前的数据
代码语言:javascript
复制
//获取第2个节点前的数据
List<String> limitList = arrayList.stream().limit(1).collect(Collectors.toList());

输出: [hello]

其他解决方案
  • guava的Lists.partition()
  • apache的ListUtils.partition()
  • 通过List的构造方法
代码语言:javascript
复制
List<String> originalList = new ArrayList<>();
// add elements to originalList

// create a new list with the same elements as originalList
List<String> newList = new ArrayList<>(originalList.subList(startIndex, endIndex));

详细方案请参考:

https://juejin.cn/post/7029519771670413325

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 技术背景
  • subList()的用法
  • subList实现
  • 解决方案
    • 通过skip()方法获取某个元素节点之后的数据
      • 通过limit()方法获取某个元素节点之前的数据
        • 其他解决方案
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档