2012-03-01 44 views
1

如果我有一个变量List.subList是否保留对原始列表的引用?

LinkedList list 

,并多次做以下提取“名单”

// Some operation that adds elements to 'list' 
// max_size = some constant 
list = (LinkedList) list.subList(list.size()-max_size, list.size()); 

做我结束了大量引用到“上一个”列表的尾部?

所以基本上我在这里要做的是删除列表的最初部分。

有没有更好的方法来移除LinkedList的初始段?我认为LinkedList的数据结构应该允许线性时间(初始段的大小线性被删除)操作。

回答

3

该代码将会失败 - 返回的子列表不是 a LinkedList<T>。样例程序:

import java.util.LinkedList; 

public class Test { 
    public static void main(String[] args) { 
     LinkedList<String> list = new LinkedList<String>(); 
     list.add("x"); 
     list.add("y"); 
     list = (LinkedList<String>) list.subList(1, 2); 
    } 
} 

输出:

Exception in thread "main" java.lang.ClassCastException: java.util.SubList 
    cannot be cast to java.util.LinkedList 
    at Test.main(Test.java:8) 

这听起来像你应该只调用removeFirst多次,因为你需要:

while (list.size() > maxSize) { 
    list.removeFirst(); 
} 
5

当一切都失败了,请参阅Javadoc

返回指定 fromIndex(包括)元素范围,独家之间的这份名单的一部分的视图。 (如果fromIndex和 toIndex相等,则返回的列表是空的。)返回的列表是 ,由此列表支持,因此返回的列表 中的非结构更改会反映在此列表中,反之亦然。返回的列表支持 此列表支持的所有可选列表操作。

如果您需要从列表的前面删除元素,那么您可以使用removeFirst,并根据需要多次调用它。

+0

其实他想删除列表的开头,所以他应该使用'removeFirst()'。 – 2012-03-01 13:13:07

+0

你知道,我无法从他如何解释他的问题中真实地分辨出来。编辑我的答案。 – Perception 2012-03-01 13:14:07

0

是的,引用的List.subList(int, int)的JavaDoc:

返回指定fromIndex(包括)元素范围为排他性之间此列表的所述部分的视图。 (如果fromIndex和toIndex相等,则返回的列表是空的。)返回列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然。

,你能做些什么来避免持有旧列表的引用(和可能产生内存泄漏)是一种基于subList创建一个新的实例:

list = new ArrayList(list.subList(list.size()-max_size, list.size())); 

这就是它!与removeFirst()相比,此方法的优势在于它可与任何List实现一起使用 - removeFirst()仅在LinkedList中定义。

1

要删除的初始段在Java中列出,请执行:

list.subList(0, numElementsToRemove).clear(); 

这是有效的,因为子列表由原始列表支持(如Javadoc所述),因此clear()被反映到原始列表的范围内。

相关问题