List subList()的一个demo
只要保证
toIndex不大于size
并且
fromIndex不大于toIndex即可
(谁会传一个负数的下标呢?)
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("1");
int size = list.size();
System.out.println(size);
System.out.println(list.subList(0, size));
System.out.println(list.subList(size, size));
}
1
[1]
[]
import org.junit.Test; import java.util.ArrayList;
import java.util.List; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is; /**
* Created by MyWorld on 2016/1/21.
*/
public class SubListDemoTest { @Test
public void ListSizeShouldEquals1_WhenSourceList9Step5() {
List<Integer> sourceList = new ArrayList<Integer>();
for (int i = 0; i < 9; i++) {
sourceList.add(i);
}
int step = 5;
List<String> targetList = SubListDemo.split(sourceList, step);
assertThat(targetList.size(), is(2));
} @Test
public void ListSizeShouldEquals2_WhenSourceList10Step5() {
List<Integer> sourceList = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
sourceList.add(i);
}
int step = 5;
List<String> targetList = SubListDemo.split(sourceList, step);
assertThat(targetList.size(), is(2));
} @Test
public void ListSizeShouldEquals3_WhenSourceList11Step5() {
List<Integer> sourceList = new ArrayList<Integer>();
for (int i = 0; i < 11; i++) {
sourceList.add(i);
}
int step = 5;
List<String> targetList = SubListDemo.split(sourceList, step);
assertThat(targetList.size(), is(3));
} }
import java.util.ArrayList;
import java.util.List; /**
* Created by MyWorld on 2016/1/21.
*/
public class SubListDemo {
public static List<String> split(List<Integer> list, int step) {
List<String> listStr = new ArrayList<String>();
int size = list.size();
int times = size / step + (size % step == 0 ? 0 : 1);
for (int i = 0; i < times; i++) {
int fromIndex = i * step;
int toIndex = (i + 1) * step;
listStr.add(list.subList(fromIndex, (toIndex < size ? toIndex : size)).toString());
}
return listStr;
}
}
tips:
java.util.List中有一个subList方法,用来返回一个list的一部分的视图。
List<E> subList(int fromIndex, int toIndex);
它返回原来list的从[fromIndex, toIndex)之间这一部分的视图,之所以说是视图,是因为实际上,返回的list是靠原来的list支持的。
所以,你对原来的list和返回的list做的“非结构性修改”(non-structural changes),都会影响到彼此对方。
所谓的“非结构性修改”,是指不涉及到list的大小改变的修改。相反,结构性修改,指改变了list大小的修改。
那么,如果涉及到结构性修改会怎么样呢?
如果发生结构性修改的是返回的子list,那么原来的list的大小也会发生变化;
而如果发生结构性修改的是原来的list(不包括由于返回的子list导致的改变),那么返回的子list语义上将会是undefined。在AbstractList(ArrayList的父类)中,undefined的具体表现形式是抛出一个ConcurrentModificationException。
因此,如果你在调用了sublist返回了子list之后,如果修改了原list的大小,那么之前产生的子list将会失效,变得不可使用。
tips: 如何删除一个list的某个区段,比如删除list的第2-5个元素?
方法是: 可以利用sublist的幕后还是原来的list的这个特性,比如
list.subList(from, to).clear();
这样就可以了。
示例代码:

public static void main(String[] args) {
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
}
//non-structural modification by sublist, reflect parentList
subList.set(0, "new 1");
for(String s : parentList){
System.out.println(s);//output: 0, new 1, 2, 3, 4
}
//structural modification by sublist, reflect parentList
subList.add(String.valueOf(2.5));
for(String s : parentList){
System.out.println(s);//output:0, new 1, 2, 2.5, 3, 4
}
//non-structural modification by parentList, reflect sublist
parentList.set(2, "new 2");
for(String s : subList){
System.out.println(s);//output: new 1, new 2
}
//structural modification by parentList, sublist becomes undefined(throw exception)
parentList.add("undefine");
// for(String s : subList){
// System.out.println(s);
// }
// subList.get(0);
}

一个很有趣的思考:如何最高效的实现一个list的split方法?
参见:http://stackoverflow.com/questions/379551/java-split-a-list-into-two-sub-lists。
http://www.cnblogs.com/gaojing/archive/2012/06/17/java-list-sublist-caution.html
List subList()的一个demo的更多相关文章
- angular开发者吐槽react+redux的复杂:“一个demo证明你的开发效率低下”
曾经看到一篇文章,写的是jquery开发者吐槽angular的复杂.作为一个angular开发者,我来吐槽一下react+redux的复杂. 例子 为了让大家看得舒服,我用最简单的一个demo来展示r ...
- 初识nginx之第一个demo
商城项目做了一个多月了,想到必须用到负载均衡,简单了解了一下nginx,首先分享第一个demo,五月份上线后,会继续分享一系列相关知识. 在nginx根目录下,用了一个园友的批处理文件nginx.ba ...
- springMvc的第一个demo
1.下载jar包 http://repo.spring.io/libs-release-local/org/springframework/spring/4.2.3.RELEASE/ 2.下载源码 j ...
- Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)
在android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,通知机制,ActionBar框架等等. ...
- 如何在WTL和MFC中使用duilib及如何静态使用duilib库!(初级讲解 附带一个Demo)
关于duilib的历史,我也就不多说了,能看到这篇文章的人都是有一定了解才能找到这个的. 我直接说下对这个库的基本使用吧. 我个人对一些好技术都是比较感兴趣的. 因为个人原因 喜欢接触一个好技术. 所 ...
- 白盒测试之gtest第一个demo
认识gtest工具后,关于它的使用,下面将用一个demo程序演示一下gtest的用法以及成果展示. 一.需要测试的C++代码: #include "myfunction.h" // ...
- 在VS中实现webService的一个demo(图解)
在VS中实现webService的一个demo(图解) 先创建一个web项目,创建好web项目后,添加新建项——web服务 在新建好的web服务文件中写如下代码: 生成当前解决方案. 新建一个winf ...
- Cocos2d-x 学习(1)—— 通过Cocos Studio创建第一个Demo
近期在工作上有了比較大的转变,自学情绪也慢慢高涨,本来一直在研究unity的技术.由于换了工作会開始接触cocos2d-x.但并不意味着停止研究unity,以后有时间还是会继续的. 公司的cocos2 ...
- 使用android的mediaplayer做成 一个demo,欢迎测试使用
附件是为一个定制视频产品而简单的写了一个demo,用来说明android的mediaplayer是如何使用的. http://files.cnblogs.com/guobaPlayer/palyerD ...
随机推荐
- SWT的CheckBoxTreeView的上级菜单与下级菜单的选中的实现
是不是很神奇? treeViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStat ...
- 教你怎么去一个APP的JSON数据,你懂的
今天闲着没事.谁让我今天是光棍节呢,算给大家一个福利.没事逛着应用市场.想找个应用高仿下,突然发现一个应用竟然跟我一个名字尼玛,尼玛应用界面做的非常easy.我认为应该不难. 惯性操作想去破解APK. ...
- Java-UrlRewrite中文api文档
安装 1. 下载jar包, 并加入到WEB-INF/lib下 2. 在WEB-INF/web.xml中增加下面的配置 <filter> <filter-name>UrlRewr ...
- 【Oracle】物理体系结构
一.ORACLE 物理体系结构 原理结构图 各部分解释: PGA: 私有内存区,仅供当前发起用户使用. 三个作用 用户登录后的session信息会保存在PGA. 运行排序.假设内存不够,orac ...
- session校验是否登录
由于一个网站要有好多页面,如果每个页面都写上检验session是否为空,太麻烦了,所以写个工具类,就方便了. 1首先创建一个类库Common 2,然后在这个类库添加引用 3在Common继承 :Sys ...
- android创建自定义对话框
创建如下自定义对话框: JAVA代码 LayoutInflater li = LayoutInflater.from(TagActivity. this); //NOTE final View Te ...
- C#中使用gRPC
C#中使用gRPC 我的这几篇文章都是使用gRPC的example,不是直接编译example,而是新建一个项目,从添加依赖,编译example代码,执行example.这样做可以为我们创建自己的项目 ...
- bellman_ford寻找平均权值最小的回路
给定一个有向图,如果存在平均值最小的回路,输出平均值. 使用二分法求解,对于一个猜测值mid,判断是否存在平均值小于mid的回路 如果存在平均值小于mid的包含k条边的回路,那么有w1+w2+w3+. ...
- C语言程序代写(qq:928900200)
1cs3157 – Advanced ProgrammingSummer 2014, Project 1, 150 pointsJune 17, 2014Follow these step-by-st ...
- 深入探索C++对象模型-语义
有三种情况,这将是一个object的内容,以及一class object早期值: class X { ... }; X x; X xx = x; // 情况1,赋值对象 e ...