文档章节

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

liujiest
 liujiest
发布于 2016/08/15 23:59
字数 568
阅读 1648
收藏 0

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

© 著作权归作者所有

共有 人打赏支持
liujiest
粉丝 7
博文 68
码字总数 29195
作品 0
杭州
程序员
私信 提问
【集合类型的并发】Collections.synchronizedList

1 :关注要点,为什么在有synchroniezed方法的同时会出现 Collections.synchronizedList 2 :知识背景: 您可能需要了解java Synchronized方法的加锁的各种机制,包括如何上锁,锁对象 3 : ...

止静
2014/08/22
0
2
发送短信如何限制1小时内最多发送11条短信

发送短信如何限制1小时内最多发送11条短信 场景: 发送短信属于付费业务,有时为了防止短信攻击,需要限制发送短信的频率,例如在1个小时之内最多发送11条短信. 如何实现呢? 思路有两个 截至到当...

黄威
06/25
0
0
归约与分组 - 读《Java 8实战》

区分Collection,Collector和collect 代码中用到的类与方法用红框标出,可从git库中查看 收集器用作高级归约 预定义收集器的功能 将流元素归约和汇总为一个值 元素分组 元素分区,分组的特殊情...

yysue
08/16
0
0
java ArrayList中的subList方法

本文是本人的学习笔记,把自己的理解总结记录下来。因本人水平有限,如果您在阅读中发现错误,还望谅解,并且希望能够告知本人改正,不胜感激! ArrayList中的subList()方法 subList方法传入的...

等到烟火清凉_
07/02
0
0
培训云计算学校,虚拟机基本结构讲解

我们要对JVM虚拟机的结构有一个感性的认知。毕竟我们不是编程人员,认知程度达不到那么深入。一个运行时的Java虚拟机实例的天职是:负责运行一个java程序。当启动一个Java程序时,一个虚拟机...

长沙千锋
05/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Accept和Content-type的意思

Accept意思是我希望接收到的数据类型 Content-type意思是我发出去的数据类型

大灰狼wow
20分钟前
1
0
Java每天10道面试题,跟我走,offer有!(五)

41.Iterator、ListIterator 和 Enumeration的区别?   迭代器是一种设计模式, 它是一个对象, 它可以遍历并选择序列中的对象, 而开发人员不需要了解 该序列的底层结构。 迭代器通常被称为...

Java干货分享
20分钟前
2
0
meta 解决页面浏览器兼容性

使用最高级的ie内核,如果支持谷歌内核,使用谷歌内核 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 这 样写可以达到的效果是如果安装了GCF,则使用GCF来渲染页面,如...

之渊
22分钟前
2
0
极验验证demo(django+vue)

在使用之前,曾经试过用阿里云的人机验证,不过在签名部分比较复杂,下载sdk后需要自己写很多,折腾了一下,还是放弃。而腾讯云的人机验证python版本有demo,直接填写keyhe1secret就可以使用...

xiaoge2016
23分钟前
1
0
浅谈js回调

js回调极为简洁,无需声明,直接通过参数传入方法实体,调用方法实体的时候,可以直接调用方法名或者方法名加参数即可,以下看例子 socket.initWebSocket(this, userName, userId, (isSucce...

Carbenson
28分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部