转自:
http://blog.csdn.net/sbfivwsll/article/details/6557611
java List.subList方法中的超级大陷阱
在使用集合中,可能常常需要取集合中的某一部分子集来进行一下操作,于是subList这个方法就映入我们的眼帘,毫不犹豫地使用。
例如以下代码:
public static void main(final String[] args) {
List<Object> lists = new ArrayList<Object>();
lists.add("1");
lists.add("2");
lists.add("3");
lists.add("4");
List<Object> tempList = lists.subList(2, lists.size());
tempList.add("6");
System.out.println(tempList); // 1
System.out.println(lists); // 2
}
代码初步写好后,可能我们想达到的效果是:往集合lists的子集合tempList中添加一个元素6,而原有的集合保持不变。
即到达这样的效果:lists = [1, 2, 3, 4],tempList = [3, 4, 6]。但是我们看到实际的结果确是lists里边也添加了元素6。
这是怎么一会事呢,通过查找java原代码我们可以看到:tempList的subList实现代码在AbstractList类里边,然而无论如何,最终的结果都是返回一个AbstractList的子类:SubList(该类是一个使用默认修饰符修饰的类,其源代码位于AbstractList.java类文件里边),
SubList类的构造方法:
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > list.size())
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
l = list;
offset = fromIndex;
size = toIndex - fromIndex;
expectedModCount = l.modCount;
}
里边,将我们原有的list对象给缓存到SubList类对象的一个属性中去了。
而SubList类的add/remove等修改元素的方法中,都使用l进行了操作:
public void add(int index, E element) {
if (index<0 || index>size)
throw new IndexOutOfBoundsException();
checkForComodification();
l.add(index+offset, element);
expectedModCount = l.modCount;
size++;
modCount++;
}
因此,当我们使用子集合tempList进行元素的修改操作时,会影响原有的list集合。所以在使用subList方法时,一定要想清楚,是否需要对子集合进行修改元素而不影响原有的list集合。
如果需要对子集合的元素进行修改操作而不需要影响原集合时,我们可以使用以下方法进行处理:
public static void main(final String[] args) {
List<Object> lists = new ArrayList<Object>();
lists.add("1");
lists.add("2");
lists.add("3");
lists.add("4");
//注意这里是和本文顶部的代码不同的....
List<Object> tempList = new ArrayList<Object>(lists.subList(2, lists.size()));
tempList.add("6");
System.out.println(tempList); // 1
System.out.println(lists); // 2
}
分享到:
相关推荐
本篇文章主要介绍了java中list数据拆分为sublist实现页面分页的简单代码,具有一定的参考价值,有需要的可以了解一下。
为什么阿里巴巴不建议在for循环中使用“+”进行字符串拼接?44 为什么阿里巴巴禁止在foreach循环里进行元素的remove/add操作?54 为什么阿里巴巴禁止工程师直接使用日志系统(Log4j、Logback) 中的API? 66 为什么...
为什么阿里巴巴不建议在 for 循环中使用“+”进行字符串拼接? 44 为什么阿里巴巴禁止在 foreach 循环里进行元素的 remove/add 操作? 54 为什么阿里巴巴禁止工程师直接使用日志系统 (Log4j、Logback) 中的 API ?...
ssd8 exercise1 答案 java 多线程 服务器 客户端 ssd8 exercise1 答案 java 多线程 服务器 客户端 ssd8 exercise1 答案 (老师给的标准答案)
subList iterator forEach sort removeIf Vector different with ArrayList 2018/3/26 ChangeLogs LinkedList ctor-2 addFirst addLast addAll add indexOf lastIndexOf peek 获取第一个元素,是 null 就返回 null ...
早前在做项目的时候, 用到RecycleView,但是在加载数据的时候,list.add(subList);然后在调用其刷新方法notifyDataSetChanged();就是出现item闪烁灯问题。这是因为recycleView自带的ItemAnimator惹的祸。那么我们...
目录前言数组与集合区别集合描述集合格式方法ArrayList实例1.add(E e)2.add(int index, E element)3.addAll(Collection c)4.clear() 与 isEmpty()5.contains(Object o)6.index... subList(int fromIndex, int toIndex)1
这样做的原因是,可以使用subList函数更轻松地将arraylist“拆分”为较小的列表。 所有重复的员工都存储在一个称为重复的数组列表中,但是出于本项目的目的,他们不再做任何事情。 通过JUnit测试隐含通过测试,以...
列表界面Java API add( T ) add( T, index ) addAll( T[] ) addAll( index, T[] ) clear() contains( T ) containsAll( T[] ) equals( List ) get( index ) hashCode() indexOf( T ) isEmpty() : bool iterator() ...
首先后台分页需要理清分页思路,把数据库里面需要分页的信息放到List集合中,然后按照页面反馈给后台的页码对List集合进行SubList切割把切完的List传到前端进行显示。 1.分页的demo文件结构图 导入的包 2.代码 ...
matlab投射转相除代码 数据结构和算法 欢迎学习数据结构和算法! 数据结构类型 ...Sublist Search | |__________ Substring Search | |__________ Jump Search | |__________ Interpolation Search | |_______
' body '.' body ::= [declarationPart] compositeStatement declarationPart ::= VAR dclList [subList] | subList dclList ::= declaration {declaration} declaration ::= idList ':' type ';' idList ::= id {',...