如何正确的截取Java List的subList

         最近在生产上,需要用多线程去处理大量的数据,这个数据在一个list里面,为了避免多个线程拉取同一个list造成多次读写,避免资源同步的问题。决定将数据分割,然后就想到了subList(int from,int to)这个方法。但是发现subList 没有根据for循环的位置进行更新,在此对subList方法进行梳理以及记录。

        List接口中有subList(int fromIndex, int toIndex)方法,这个方法返回实现了List接口的SubList的实例,而非当前同类型的实例。Sublist可以简单理解是子List,这个SubList是在AbstractList中定义的,因此只能是包内可见,我们在外面没办法直接访问

        它返回原来list的从[fromIndex, toIndex)之间这一部分的视图,之所以说是视图,是因为实际上,返回的list是靠原来的list支持的。所以,你对原来的list和返回的list做的“非结构性修改”(non-structural changes),都会影响到彼此对方。所谓的“非结构性修改”,是指不涉及到list的大小改变的修改。相反,结构性修改,指改变了list大小的修改。

        那么,如果涉及到结构性修改会怎么样呢?

        如果发生结构性修改的是返回的子list,那么原来的list的大小也会发生变化;而如果发生结构性修改的是原来的list(不包括由于返回的子list导致的改变),那么返回的子list语义上将会是undefined。在AbstractList(ArrayList的父类)中,undefined的具体表现形式是抛出一个ConcurrentModificationException。因此,如果你在调用了sublist返回了子list之后,如果修改了原list的大小,那么之前产生的子list将会失效,变得不可使用。

        如果你对一个 List 进行过 subList() 的操作之后,

        1. 千万不要再对原 List 进行任何改动的操作(例如: 增删改), 查询和遍历倒是可以. 因为如果对原 List 进行了改动, 那么后续只要是涉及到子 List 的操作就一定会出问题. 而至于会出现什么问题呢? 具体来说就是:
        (1) 如果是对原 List 进行修改 (即: 调用 set() 方法) 而不是增删, 那么子 List 的元素也可能会被修改 (这种情况下不会抛出并发修改异常).
        (2) 如果是对原 List 进行增删, 那么此后只要操作了子 List , 就一定会抛出并发修改异常.

        2. 千万不要直接对子 List 进行任何改动的操作(例如: 增删改), 但是查询和间接改动倒是可以. 不要对子 List 进行直接改动, 是因为如果在对子 List 进行直接改动之前, 原 List 已经被改动过, 那么此后在对子 List 进行直接改动的时候就会抛出并发修改异常.

如果想要实现String.split的效果,争取的截取List的subList ,需要按照如下的方法:

List sub=one.subList(...);
List two=new XxxList(sub);
sub.clear();

————————————————
参考链接:https://blog.csdn.net/clevergump/article/details/51105235 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ranjinghang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值