java sublist_java中List.subList()方法的使用

sublist返回的东西,官方解释:Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex bulabula。一个View,视图,想到了数据库视图。

做个实验:

public static void main(String[] args) {

List list = new ArrayList<>();

list.add(1);

list.add(2);

list.add(3);

list.add(4);

List sub = list.subList(0, 2);// 1,2

sub.add(5);

sub.add(6);

System.out.println("sub:" + sub);

System.out.println("list:" + list);

}

sub:[1, 2, 5, 6]

list:[1, 2, 5, 6, 3, 4]

不仅是sublist,原来的list也增加了。

System.out.println(sub.getClass());

class java.util.ArrayList$SubList

有趣,返回的不是ArrayList,而是里面的子类,源码:

public List subList(int fromIndex, int toIndex) {

subListRangeCheck(fromIndex, toIndex, size);

return new SubList(this, 0, fromIndex, toIndex);

}

private class SubList extends AbstractList implements RandomAccess {

private final AbstractList parent;

private final int parentOffset;

private final int offset;

int size;

SubList(AbstractList 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 get(int index) {

rangeCheck(index);

checkForComodification();

return ArrayList.this.elementData(offset + index); // 查询也是查的父列表

}

public void add(int index, E e) {

rangeCheckForAdd(index);

checkForComodification();

parent.add(parentOffset + index, e); //父列表也【插入】了

this.modCount = parent.modCount;

this.size++;

}

}

于是可以这样这样移除我不想要的数据:

public static void main(String[] args) {

List list = new ArrayList<>();

list.add(1);

list.add(2);

list.add(3);

list.add(4);

list.subList(3, list.size()).clear();

System.out.println("list:" + list);

}

list:[1, 2, 3]

我突然想这样试一下:

public static void main(String[] args) {

List list = new ArrayList<>();

list.add(1);

list.add(2);

list.add(3);

list.add(4);

List sub = list.subList(0, 2);// 1,2

sub.add(5);

sub.add(6);

sub.clear();

list.add(7);

list.add(8);

System.out.println("sub:" + sub);

System.out.println("list:" + list);

}

Exception in thread "main" java.util.ConcurrentModificationException

at java.util.ArrayList$SubList.checkForComodification(Unknown Source)

at java.util.ArrayList$SubList.listIterator(Unknown Source)

at java.util.AbstractList.listIterator(Unknown Source)

at java.util.ArrayList$SubList.iterator(Unknown Source)

at java.util.AbstractCollection.toString(Unknown Source)

at java.lang.String.valueOf(Unknown Source)

at java.lang.StringBuilder.append(Unknown Source)

at code.MapTest.main(MapTest.java:20)

果然报错了。。。

直接结论:

前面子类的源码get方法有这么一句: checkForComodification();

private void checkForComodification() {

if (ArrayList.this.modCount != this.modCount)

throw new ConcurrentModificationException();

}

modCount和父List不一样就报错,这个变量表示当前链表【变化】了几次。

有人解释的很好很详细,Mark:

https://www.zhihu.com/question/24086463

http://www.cnblogs.com/dolphin0520/p/3933551.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值