List.subList是否保留对原始列表的引用?

时间:2012-03-01 13:07:20

标签: java

如果我有变量

LinkedList list

并反复执行以下操作以提取“list”的尾部

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

我最终会引用很多对“上一个”列表的引用吗?

所以基本上我在这里要做的就是删除列表的初始段。

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

4 个答案:

答案 0 :(得分:5)

当其他所有方法都失败时,请咨询Javadoc

  

返回指定列表中此列表部分的视图   fromIndex,inclusive,toIndex,exclusive。 (如果fromIndex和   toIndex相等,返回的列表为空。)返回的列表是   此列表支持,因此返回列表中的非结构更改   反映在此列表中,反之亦然。返回的列表支持   此列表支持的所有可选列表操作。

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

答案 1 :(得分: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();
}

答案 2 :(得分:1)

要删除Java中列表的初始段,请执行以下操作:

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

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

答案 3 :(得分:0)

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

  

在指定的fromIndex(包含)和toIndex(不包括)之间返回此列表部分的视图。 (如果fromIndex和toIndex相等,则返回的列表为空。)返回的列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然

如果要避免保留对旧列表的引用(并可能创建内存泄漏),可以执行的操作是基于subList创建新实例:

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

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