我可以从子列表中检索开始和结束索引吗?

时间:2013-01-06 06:36:45

标签: java list collections

我正在使用一个使用异构“插槽”列表的库。此列表中有几种类型的插槽(输入,输出,存储,......),每个插槽都在一个连续的范围内。我想使用list.subList(start, end)将这些类型中的每一个拉到自己的列表中以便更好地管理我,但我仍然需要调用库方法,这些方法需要原始列表中的索引,所以我会需要一些方法来制作我的子列表中的那些。

是否可以提取用于创建子列表的原始fromIndextoIndex?或者我是否需要自己执行簿记?

3 个答案:

答案 0 :(得分:1)

由于List.sublist返回List<T>,因此无法检索用于创建子列表的from和to索引。但是,没有什么可以阻止你自己存储这些索引:你可以自己编写一个包装器来保存索引,如下所示:

class SubList<T> implements List<T> {
    private final int fromIndex;
    private final int toIndex;
    private final List<T> wrapped;
    public SubList<T>(List<T> orig, int from, int to) {
        wrapped = orig.subList(from, to);
        fromIndex = from;
        toIndex = to;
    }
    public int getFromIndex() {
        return fromIndex;
    }
    public int getToIndex() {
        return toIndex;
    }
    public T get(int index) {
        return wrapped.get(index);
    }
    public int indexOf(object o) {
        return wrapped.indexOf(o);
    }
    ...
    // Implement the remaining List<T> methods here
}

答案 1 :(得分:1)

你可以用反射来做。所有JCF列表都继承AbstracList.sublist

public List<E> subList(int fromIndex, int toIndex) {
    return (this instanceof RandomAccess ?
            new RandomAccessSubList<>(this, fromIndex, toIndex) :
            new SubList<>(this, fromIndex, toIndex));
}

RandomAccessSublist是SubList的子类。这是SubList

class SubList<E> extends AbstractList<E> {
    private final AbstractList<E> l;
    private final int offset;
    private int size;

所以你可以从这里拿你的索引。

答案 2 :(得分:0)

是的,如果您需要开始和结束指数,则必须进行簿记。可以扩展ArrayList并覆盖subList,以便返回的CustomList具有支持列表的开始和结束索引。

但您可以在subList上执行clear() indexOf()之类的所有操作,您可以处理子列表,这将反映在父列表中。这在大多数情况下都有帮助。

来自Javadoc

  

返回指定fromIndex(包含)和toIndex(独占)之间此列表部分的视图。 (如果fromIndex和toIndex相等,则返回的列表为空。)返回的列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然。返回的列表支持此列表支持的所有可选列表操作。   此方法消除了对显式范围操作(对于数组通常存在的排序)的需要。任何需要列表的操作都可以通过传递subList视图而不是整个列表来用作范围操作。例如,以下习语从列表中删除了一系列元素:

  list.subList(from, to).clear();
  

可以为indexOf和lastIndexOf构造类似的习语,Collections类中的所有算法都可以应用于subList。   如果支持列表(即,此列表)在结构上以除了返回列表之外的任何方式进行修改,则此方法返回的列表的语义将变为未定义。 (结构修改是那些改变了这个列表的大小,或以其他方式扰乱它的方式,正在进行的迭代可能会产生不正确的结果。)