转自:
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(int fromIndex, int toIndex)`方法,用于返回列表的一个子列表,这个子列表是从`fromIndex`(包含)到`toIndex`(不包含)的元素。这意味着,你可以根据当前页数和每页的记录数...
在Java编程中,`subList`方法是`ArrayList`、`LinkedList`等集合类的一个重要功能,它允许我们从原始列表中创建一个子列表,这个子列表是原列表的一个视图,而不是复制。当我们调用`subList`时,对子列表的操作会...
在Java中, List对象的分页思想可以通过使用subList()方法来实现。subList()方法可以将一个大的List对象分割成多个小的List对象,每个小的List对象包含一定数量的元素。例如,以下代码将一个大的List对象分割成多个...
2. **并发修改异常**:如果原ArrayList在多线程环境下被修改,而subList同时也在另一个线程中使用,可能会引发`ConcurrentModificationException`,因为修改原ArrayList会影响subList的视图。 3. **不可预测的行为*...
在Java编程中,多线程技术是处理大数据批量导入或导出的重要手段。它能有效提升程序执行效率,尤其在数据库操作这样的I/O密集型任务中。本项目以"java多线程实现大批量数据导入源码"为题,旨在通过多线程策略将大量...
### Java编程中常见的坑 #### 1. 自动拆箱时遇到null会抛出空指针异常 在Java中,当我们尝试将一个包装类类型的变量(例如`Integer`)自动拆箱为基本类型(例如`int`)时,如果该包装类变量为`null`,那么Java会抛...
在这个“java集合框架的使用”主题中,我们将深入探讨如何利用Java集合框架进行基本的集合运算,包括散列集合、求子集以及集合的交和并。 首先,我们要理解Java集合框架的基本层次结构。它主要包括接口(如List、...
2. HashMap容量初始化:在Java中使用HashMap时,建议预先设置一个合适的初始化容量。阿里巴巴Java开发手册建议初始化HashMap的容量大小是因为HashMap在内部维护了一个负载因子,当Map中的元素数量达到容量与负载因子...
因此,Java开发手册建议我们不要在for循环中使用“+”进行字符串拼接,而是使用StringBuilder来拼接字符串。 8.为什么禁止在foreach循环里进行元素的remove/add操作? 在Java中,我们经常使用foreach循环来遍历...
在Java编程中,生成十个不重复的随机数是一项常见的任务,尤其在进行数据模拟、测试或者游戏设计等场景。要实现这个功能,我们需要利用到Java的集合框架和Math类中的随机数生成方法。下面我们将详细讲解如何实现这个...
- **性能考量**:在循环中使用"+"拼接字符串会导致频繁创建新的字符串对象,尤其是在大量迭代的情况下,这将严重影响性能。 - **优化方案**:推荐使用`StringBuilder`或`StringBuffer`类来高效地拼接字符串,这些类...
- 使用构造函数初始化对象,避免在类中使用静态初始化块。 4. **异常处理**: - 异常不应该被忽视,必须被捕获并处理,或通过抛出声明。 - 不要使用`catch (Exception e)`这样的通用捕获,应具体到异常类型。 -...
Java作为一种广泛使用的编程语言,提供了丰富的库和工具来实现时间序列算法。本篇文章将深入探讨时间序列预测的基本原理,Java实现的关键步骤,以及如何通过实际的代码示例进行实践。 时间序列数据是按特定时间顺序...
在Java开发中,处理Excel数据是一项常见的任务,Apache POI是一个强大的库,它允许开发者读取、创建和修改Microsoft Office格式的文件,包括Excel。本篇文章将深入探讨如何使用Java和Apache POI来实现Excel模板的...
5. 不推荐在for循环中使用“+”进行字符串拼接:在for循环中使用字符串拼接操作符“+”进行字符串的拼接效率低下,因为每次拼接都会产生一个新的字符串对象。这会导致频繁的内存分配和垃圾回收,影响性能。使用...
在本教程中,我们将深入探讨如何创建和使用`Java List`。 首先,我们需要导入`java.util.List`和`java.util.ArrayList`(或`java.util.LinkedList`)这两个包。`ArrayList`和`LinkedList`都是`List`接口的实现类,...
标题 "java.lang.Exception: java.lang.IllegalArgumentException: firstMovedIndex, lastMove" 描述了一个Java编程中的异常情况。这个异常通常发生在尝试执行一个不合法的操作时,例如数组或集合操作超出了其边界。...
根据提供的文件信息,标题与描述均指向了Java中List的操作方法。然而,给出的部分内容却是一段关于导入Excel文件到Web应用中的代码片段,并没有直接涉及List的...希望本文能够帮助大家更好地理解和使用Java中的List。
4. **集合使用**:对于Java集合框架的使用,手册给出了很多实用建议,比如避免使用`ArrayList`的`subList`进行遍历,使用`CopyOnWriteArrayList`替代`Vector`在并发场景下,以及合理选择`HashMap`与`...