javaAPI深入理解(1)如何截短一个List以及List.subList()方法的坑
来源:互联网 发布:mac查看股票行情 编辑:程序博客网 时间:2024/05/07 22:46
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 work for (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。
0 0
- javaAPI深入理解(1)如何截短一个List以及List.subList()方法的坑
- javaAPI深入理解(1)如何截断一个List以及List.subList()方法的坑
- javaAPI深入理解(2)Collection,List的设计,ListIterator与Iterator,RandomAccess,List排序、逆序以及其他
- 小心List的subList方法
- list集合的 sublist方法
- 【Java】List的subList方法
- List方法 subList详解
- 慎用List.subList方法
- java List.subList方法
- 【Java】List的subList方法参数误导
- List 的subList()方法使用注意事项
- List 的 subList方法注意点
- List 的 subList
- 利用List的subList方法,实现对List分页
- 慎用List中的subList方法
- List subList()
- List subList()
- list.subList
- SASS界面编译工具——Koala的使用
- 前端ajax传中文到后端解决编码问题
- 从零实现一个高性能网络爬虫(一)网络请求分析及代码实现
- 前台向后台传参
- php实现短信群发
- javaAPI深入理解(1)如何截短一个List以及List.subList()方法的坑
- Invert Binary Tree
- go实现ketama哈希
- Move Zeroes
- DataList实现专题+评论
- 执行 java class 文件引入jar包
- 开通博客的想法
- 《FreeSWITCH: VoIP实战》:SIP 模块
- 堆和栈的区别