java中List.subList()方法的使用
博客专区 > liujiest 的博客 > 博客详情
java中List.subList()方法的使用
liujiest 发表于1年前
java中List.subList()方法的使用
  • 发表于 1年前
  • 阅读 488
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 十分钟定制你的第一个小程序>>>   

摘要: 今天老大让改个接口,对于某个业务处理后得到的list最多只返回9个,好吧挺简单的。但是,我是个认真的boy,虽然马上脑海浮现出的看过无数次却从来没用的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<Object> list = new ArrayList<>();
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		List<Object> 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<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, 0, fromIndex, toIndex);
}


private class SubList extends AbstractList<E> implements RandomAccess {
        private final AbstractList<E> parent;
        private final int parentOffset;
        private final int offset;
        int size;

        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 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<Object> 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<Object> list = new ArrayList<>();
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		List<Object> 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

标签: java list sublist
共有 人打赏支持
粉丝 7
博文 64
码字总数 26587
×
liujiest
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: