文档章节

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

liujiest
 liujiest
发布于 2016/08/15 23:59
字数 568
阅读 2112
收藏 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
粉丝 8
博文 75
码字总数 34353
作品 0
杭州
程序员
私信 提问
【集合类型的并发】Collections.synchronizedList

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

止静
2014/08/22
0
2
java ArrayList中的subList方法

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

等到烟火清凉_
2018/07/02
0
0
Java ThreadLocal 类的知识点解读

说起 Java 中的 ThreadLocal 类,可能很多安卓开发人员并不是很熟悉,毕竟很少有使用到的地方。但是如果你仔细分析过 Handler 源码的话,就一定见过这个类的出现。而 Handler 机制又是安卓知...

亦枫
2018/10/29
0
0
ThreadLocal 源码解析

本文将从以下几个方面介绍 前言 栗子 类图 ThreadLocal源码分析 ThreadLocalMap 源码分析 ThreadLocal 可能会导致内存泄漏 前言 ThreadLocal 顾名思义就是在每个线程内部都会存储只有当前线程...

tsmyk0715
2018/10/28
0
0
云计算高级培训,Tomcat运维JVM 虚拟机常识

云计算高级培训,Tomcat运维JVM 虚拟机常识,作为了解JVM 虚拟机的开始。我们很有必要弄明白以下问题。 所谓虚拟机,就是一台虚拟的计算机。他是一款软件,用来执行一系列虚拟计算机指令。大...

长沙千锋
2018/05/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

大数据反欺诈技术架构

一年多以前,有朋友让我聊一下你们的大数据反欺诈架构是怎么实现的,以及我们途中踩了哪些坑,怎么做到从30min延迟优化到1s内完成实时反欺诈。当时呢第一是觉得不合适,第二也是觉得场景比较...

微笑向暖wx
26分钟前
1
0
flink-系统内部消息传递的exactly once语义

At Most once,At Least once和Exactly once 在分布式系统中,组成系统的各个计算机是独立的。这些计算机有可能fail。 一个sender发送一条message到receiver。根据receiver出现fail时sender如...

xtof
33分钟前
1
0
iOS程序执行顺序和UIViewController 的生命周期(整理)

说明:此文是自己的总结笔记,主要参考: iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 UIView的生命周期 言叶之庭.jpeg 一. iOS程序的启动执行顺序 程序启动顺序图 iO...

壹峰
35分钟前
1
0
配置网络、远程登录、Linux秘钥认证

配置网络 一台服务器安装完系统之后不管是为了方便管理还是业务需要,我们都要给它配置ip地址。让机器能够联网。在现实的生产环境的当中,往往我们给服务器配置的ip都是提前规划好的,但是在...

李超小牛子
39分钟前
1
0
dotConnect for Oracle入门指南(五):检索和修改数据

【下载dotConnect for Oracle最新版本】 dotConnect for Oracle(原名OraDirect.NET)建立在ADO.NET技术上,为基于Oracle数据库的应用程序提供完整的解决方案。它为设计应用程序结构带来了新的...

电池盒
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部