ArrayList.subList方法

List<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
List<String> subList = list.subList(0, 2);
System.out.println(subList); //[111, 222]

ArrayList.subList返回的是其内部类 SubList 的实例(原始列表的一个视图)。

对原来的list和返回的list做的“非结构性修改”(non-structural changes),都会影响到对方。
所谓的“非结构性修改”是指不涉及到list的大小改变的修改。相反,结构性修改,指改变了list大小的修改。

  • 如果发生结构性修改的是返回的子list,那么原来的list的大小也会发生变化;
  • 而如果发生结构性修改的是原来的list(不包括由于返回的子list导致的改变),那么返回的子list语义上将会是undefined。在AbstractList(ArrayList的父类)中,undefined的具体表现形式是抛出一个ConcurrentModificationException。

这也很好理解,在Java的继承体系中,父类永远不知道自己有没有/有多少子类。


private class SubList extends AbstractList<E> implements RandomAccess {}

查看继承层次可以知道,Array.SubList 不能强制转换为ArrayList类型。

private class SubList extends AbstractList<E> implements RandomAccess {
    private final AbstractList<E> parent; //宿主(原ArrayList)                             
    private final int parentOffset; //                                    
    private final int offset; //                                         
    int size; //SubList列表的长度                                                          

    SubList(AbstractList<E> parent,                                    
            int offset, int fromIndex, int toIndex) {                  
        this.parent = parent;                                          
        this.parentOffset = fromIndex;                                 
        this.offset = offset + fromIndex;                              
        this.size = toIndex - fromIndex;                               
        this.modCount = ArrayList.this.modCount;                       
    }  
    public E set(int index, E e) {                                    
        rangeCheck(index);  //检查是否越界                                          
        checkForComodification(); // 检查modCount                                    
        E oldValue = ArrayList.this.elementData(offset + index);      
        ArrayList.this.elementData[offset + index] = e;               
        return oldValue;                                              
    }
    public void add(int index, E e) {             
        rangeCheckForAdd(index);                  
        checkForComodification();                 
        parent.add(parentOffset + index, e);      
        this.modCount = parent.modCount;          
        this.size++;                              
    }                                                                                                              
    //...
}                                                                

我们可以方便的使用如下代码来删除某个区间的序列。

list.subList(from, to).clear();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

N3verL4nd

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

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

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

打赏作者

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

抵扣说明:

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

余额充值