Java中List的subList()方法及使用注意事项

List<Object> list = new Arraylist<>();List<Object> subList = list.subList(0, 5);

其中subList(0, 5)取得的是下标为0到4的元素,不包含下标为5的元素.

java.util.List中的subList方法返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

List<E> subList(int fromIndex, int toIndex);

fromIndex - subList 的低端(包括)
toIndex - subList 的高端(不包括)

此方法省去了显式范围操作(此操作通常针对数组存在)。通过传递 subList 视图而非整个列表,期望列表的任何操作可用作范围操作。例如,下面的语句从列表中移除了元素的范围:

list.subList(from, to).clear();

下面通过代码来理解subList方法的使用

 List<String> parentList = new ArrayList<String>();for(int i = 0; i < 5; i++){parentList.add(String.valueOf(i));}List<String> subList = parentList.subList(1, 3);for(String s : subList){System.out.println(s);//output: 1, 2}subList.clear();System.out.println(parentList.size());//output: 3List<String> subList = parentList.subList(1, 3);在subList集合中的元素{1,2}中的第0的位置设置为new 1,即把1设置成了new 1subList.set(0, "new 1"); for(String s : parentList){System.out.println(s);//output: 0, new 1, 2, 3, 4}subList.add(String.valueOf(2.5));for(String s : parentList){System.out.println(s);//output:0, 1, 2, 2.5, 3, 4}//如果你在调用了sublist返回了子list之后,如果修改了原list的大小,那么之前产生的子list将会失效,变得不可使用。报 java.util.ConcurrentModificationExceptionparentList.add("undefine");for(String s : subList){System.out.println(s);}subList.get(0);

注意事项

ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException 异常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList.

说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是 ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。

在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、 删除均会产生 ConcurrentModificationException 异常。

List<Book> books = new ArrayList<>();Book book1 = new Book(1,"语文");books.add(book1);Book book2 = new Book(2,"数学");books.add(book2);Book book3 = new Book(1,"英语");books.add(book3);Book book4 = new Book(1,"网络安全");books.add(book4);Book book5 = new Book(1,"C语言程序设计");books.add(book5);System.out.println("原来的list:"+books.toString());List<Book> subList = books.subList(0, 1);for(int i=0;i<subList.size();i++){subList.get(i).setBookName(subList.get(i).getBookName()+"-updated");}System.out.println("修改后list:"+books.toString());

img


removeRange(int, int);这个方法AbstractList并没有暴露出来,我们应该如何得到一个截短的list?

1 如何得到一个list某个范围的子集sublist

首先想到sublist(int, int)方法
注意此方法参数左闭右开。
测试如下

1.1 修改sublist会影响原来的list

LinkedList<String> ll = new LinkedList<>();
ll.add("a");
ll.add("b");
ll.add("c");
List<String> l2 =  ll.subList(1, 2);//[)
l2.add("new");
System.out.println(ll);
System.out.println(l2);

运行结果:

[a, b, new, c]
[b, new]

可见sublist是快照,sulist插入会影响原list

1.2 修改原list,则sublist的所有操作会报错

LinkedList<String> ll = new LinkedList<>();
ll.add("a");
ll.add("b");
ll.add("c");
List<String> l2 =  ll.subList(1, 2);//[)
ll.add("d");
System.out.println(ll);
System.out.println(l2);

Exception in thread “main” java.util.ConcurrentModificationException
at java.util.SubList.checkForComodification(AbstractList.java:769)

可见如果更改了原来的list,sublist的任何操作都会报错,包括get() size(),listIterator()等所有调用checkForComodification()的地方。

2 如何正确的截断一个List?

subList()返回的是List!是Sublist,而不是原来的类型。

2.1在java.util.AbstractList.subList(int fromIndex, int toIndex)的定义,返回的是java.util.SubList.SubLis:

 public List<E> subList(int fromIndex, int toIndex) {return (this instanceof RandomAccess ?new RandomAccessSubList<>(this, fromIndex, toIndex) :new SubList<>(this, fromIndex, toIndex));}声明:class SubList<E> extends AbstractList<E>{}

2.2 LinkedList并没有覆盖这个方法.ArryList自己覆盖了这个方法,返回的是java.util.ArrayList.SubList:

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 {}

看来ArryList处处体现出RandomAccess接口的特性——支持随机访问。

2.3 我们看一下java.util.AbstractList.clear()方法,这正是我们需要的,Sublist的clear就是这个方法

public void clear() {removeRange(0, size());
}

2.3.1 ArrayList的覆盖

public void clear() {modCount++;// clear to let GC do its workfor (int i = 0; i < size; i++)elementData[i] = null;size = 0;
}

2.3.2 LinkedList的覆盖

public void clear() {for (Node<E> x = first; x != null; ) {Node<E> next = x.next;x.item = null;x.next = null;x.prev = null;x = next;}first = last = null;size = 0;modCount++;
}

3 根据1和2

截短一个List的正确姿势:

list.subList(from, to).clear();

总之:
subList是返回一个镜像而不是新示例 用了 得保证原来的list不能更改。
之前的抛异常是因为更改了原来的list而要使用sublist的时候必然报异常。
clear的这个跟这个问题说的是如何获得一个list的某一段顺便释放其他节点。
这个操作后原来的list会截取出来 类型不变。
而subList实际上返回的是java.util.Sublist或者java.util.ArrayList.Sublist。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/554929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php有关卡的消消乐源码,查看“宝可消消乐/活动关卡/得分挑战关卡/超梦”的源代码...

因为以下原因&#xff0c;您没有权限编辑本页&#xff1a;您所请求的操作仅限于该用户组的用户使用&#xff1a;用户您可以查看与复制此页面的源代码。关卡{| {{classcolortable|type|psychic|widthfull}}|{{Shuffle Stage| stage 得分挑战关卡| name 超梦| number 150| for…

SpringBoot操作hbase

1&#xff0c;添加依赖&#xff08;客户端版本和 HBase 版本需要保持一致&#xff0c;否则可能会遇到不兼容的问题。&#xff09; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId>&…

php 域名白名单,域名白名单验证

验证域名是否在白名单中是编程时常用到的功能&#xff0c;对安全性有要求的项目中都有该功能。常见的使用场景有登录后回跳&#xff0c;跳转到外站时弹出安全提示等。知乎登录后回跳&#xff1b;只要有登录的地方就需要用到来源回跳。我们在一个页面www.baidu.com 调用知乎的登…

Java Socket与Html5 websocket通信

一、Mysocket.java文件 import org.springframework.stereotype.Component;import javax.websocket.*; import javax.websocket.server.*;// ws://localhost:8080/ws/Tom ServerEndpoint("/ws/{user}") Component public class MySocket {private String currentUse…

matlab 由移相角如何产生移相脉冲,整流电路控制角移相范围是怎么确定的?

整流电路控制角移相范围是怎么确定的&#xff1f;2019-03-14【FrancisQu的回答(28票)】:谢邀^^一言以蔽之&#xff0c;整流电路控制角的范围取决于整流电路直流输出电压平均值时所得的控制角&#xff0c;详细分析如下。基本概念&#xff1a;触发延迟角(控制角)——从晶闸管开始…

php编程对联,形容程序员的对联大全

程序员&#xff0c;是从事程序开发、维护的专业人员。现在有一些形容程序员的对联&#xff0c;学习啦小编为大家整理了一些&#xff0c;感兴趣的&#xff0c;欢迎大家阅读。形容程序员的对联摘抄上联&#xff1a;莫道运维无姝丽&#xff0c;下联&#xff1a;谁言开发不风情?横…

SpringBoot 实现SSE 服务器发送事件

SSE 全称Server Sent Event&#xff0c;直译一下就是服务器发送事件&#xff0c;一般的项目开发中&#xff0c;用到的机会不多&#xff0c;可能很多小伙伴不太清楚这个东西&#xff0c;到底是干啥的&#xff0c;有啥用 本文主要知识点如下&#xff1a; SSE 扫盲&#xff0c;应…

php多表递归查询,使用公用表表达式的递归查询

微软从SQL2005起引入了CTE(Common Table Expression)以强化T-SQL。公用表表达式 (CTE) 具有一个重要的优点&#xff0c;那就是能够引用其自身&#xff0c;从而创建递归 CTE。递归 CTE 是一个重复执行初始 CTE 以返回数据子集直到获取完整结果集的公用表表达式。当某个查询引用递…

php如何把图片存入oracle,在PHP中将图片存放ORACLE中

我这里提供一个用PHP操纵blob字段的例子给你&#xff0c;希望能有所帮助&#xff01;这个例子是把用户上传的图片文件存放到BLOB中。假设有一个表&#xff0c;结构如下&#xff1a;CREATE TABLE PICTURES (ID NUMBER,DESCRIPTION VARCHAR2(100),PICTURE BLOB);然后是用来处理数…

Springboot之整合SSE实现消息推送

Springboot之整合SSE实现消息推送 前言 项目中涉及到部分请求&#xff0c;后端处理时间较长&#xff0c;使用常规Http请求&#xff0c;页面等待时间太长&#xff0c;对用户不友好&#xff0c;故考虑使用长链接进行消息推送&#xff0c;可选方案有WebSocket、SSE&#xff0c;We…

SQL按某字段去重 保留按某个字段排序最大值

select * from tablename as a where not exists ( select 1 from tablename as bwhere b.namea.name and b.id>a.id)talename&#xff1a;要去重复的表 name:需要去重复的字段&#xff0c;可以有多个字段 ID&#xff1a;取id字段最大 例子&#xff1a; create table ta…

oracle将字符串的日期格式化,oracle格式化字符串 oracle 怎么把字符串转换成日期...

Oracle数据库中如何将字符串格式化为日期可以用 to_date(日期类型字符串,要转化的日期类型)函数进行日期格式转换 sql&#xff1a;select to_date(1990-12-12 12:12:32,yyyy-MM-dd hh24:mi:ss) from dual; 解释&#xff1a;此语句的输出结果就是 “1990-12-12 12:12:32”(日期类…

SQL中只要用到聚合函数就一定要用到group by 吗?

SQL中只要用到聚合函数就一定要用到group by 吗? 今天记录一个弱智问题&#xff0c;一直没发现这个问题。 答&#xff1a;看情况 1、当聚集函数和非聚集函数出现在一起时&#xff0c;需要将非聚集函数进行group by 2、当只做聚集函数查询时候&#xff0c;就不需要进行分组了…

oracle排名怎么去除空值影响,Oracle排序中常用的NULL值处理方法

1、缺省处理Oracle在Order by 时缺省认为null是最大值&#xff0c;所以如果是ASC升序则排在最后&#xff0c;DESC降序则排在最前2、使用nvl函数nvl函数可以将输入参数为空时转换为一特定值&#xff0c;如nvl(employee_name,’张三’)表示当employee_name为空时则返回’张三’&a…

Vue中npm run dev 和 npm run serve区别

在运行vue文件时&#xff0c;需要进行npm操作&#xff0c;但我们发现&#xff0c;有时候用的是npm run serve&#xff0c;而有的时候用的是npm run dev&#xff0c;二者有什么区别 在我们运行一些 vue 项目的时候&#xff0c;输入npm run serve或者 npm run dev的其中一个时&a…

SpringBoot导出数据为PDF

一、SpringBoot导出数据为PDF 1、添加所需依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.11</version> </dependency> <dependency><groupId>com.itextpdf.…

php安装mem+cache扩展,安装memcached及php扩展

用的是centos系统1、安装memcachedyum -y install memcached安装完成后&#xff0c;memcached -h应该会出现memcached 参数说明2、memcached配置文件vi /etc/sysconfig/memcachedPORT"11210"USER"memcached"MAXCONN"1024"CACHESIZE"64"…

Springboot集成支付宝沙箱支付(完整版)

开发前准备 easy支付官方文档&#xff1a;https://opendocs.alipay.com/open/009ys9 通用版文档&#xff1a;https://opendocs.alipay.com/open/02np94 支付宝沙箱的配置 注册支付宝开发者账户&#xff0c;进入开发者控制台 https://openhome.alipay.com/platform/developer…

mongodb 数组查询 php,关于PHP,查询mongodb里的数组的问题

这一个记录{ “_id” : ObjectId(“56bb7aafa1164ef44e000029”), “qishu” : 21, “shuzi” : [ 69, 15, 86, 40, 20, 67, 46, 13, 36, 23, 33, 26, 9, 49, 81, 96, 65, 31, 52, 75, 99, 6, 39, 74, 47, 42, 1, 94, 82, 91, 5, 27, 30, 28, 7, 90, 34, 37, 79, 70, 18, 87, 5…

Springboot集成支付宝沙箱支付(退款功能)

包括&#xff1a; 支付宝沙箱 支付 异步通知 退款功能 正式版本的sdk 通用版本SDK文档&#xff1a;https://opendocs.alipay.com/open/02np94 <dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><…