循环数组列表(扩展数组列表)

2022-09-02 05:18:32

所以我的程序需要一种循环 ArrayList。

关于它的唯一循环必须是get(int index)方法,这是原始的:

    /**
     * Returns the element at the specified position in this list.
     *
     * @param  index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */ 
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

如果索引为 -1,则应获取索引为 ArrayList.size()-1 的元素,如果索引为 ArrayList.size(),则应获取索引为 0 的元素。

在我看来,实现这个目标的最简单方法是简单地从java.util包扩展ArrayList,并重写get(int索引),这样它就不会为上面的两个索引抛出IndexOutOfBoundsException,而是将它们更改为我想要的。它将为任何其他超出边界的索引抛出 IndexOutOfBoundsException。

但是,由于 elementData(index) 访问一个

private transient Object[] elementData;

我无法让它工作,因为我的班级看不到它,因为它是私有的。

另外,我不想为此使用任何外部库,仅仅是因为我认为没有适合我的需求,因为我不想要真正的circularArray,而只是它的一部分功能,其余部分是常规的ArrayList。

所以我有两个问题:

我怎样才能做到这一点?有没有办法在不将整个ArrayList类以及抽象集合,集合和可迭代复制到我的程序中的情况下做到这一点?即使对我来说,这似乎也是糟糕的设计。

如果我能以某种方式让它工作,还有什么我应该注意的吗?如果我进行上述更改,这会仅按照我想要的方式更改类的行为,还是会存在任何其他不需要的行为更改?

编辑:感谢您的回答,这是我所做的:

import java.util.ArrayList;

public class CircularArrayList<E> extends ArrayList<E>
{
    private static final long serialVersionUID = 1L;

    public E get(int index)
    {
        if (index == -1)
        {
            index = size()-1;
        }

        else if (index == size())
        {
            index = 0;
        }

        return super.get(index);
    }
}

它将环绕 ArrayList,但只能环绕一个。我希望它抛出一个异常,如果我尝试访问任何其他元素,但第一个和最后一个元素除了它们的常规 ArrayList 索引之外的任何内容。


答案 1

您可以扩展 ArrayList 类以更改方法的功能,而无需访问该字段:getelementData

public class CircularList<E> extends ArrayList<E> {

    @Override
    public E get(int index) {
        return super.get(index % size());
    }
}

该方法仍将执行范围检查(但这些检查永远不会失败)。super.get

您应该知道,这样做可能会给 ArrayList 提供不稳定的索引。如果列表的大小发生变化,则正常范围之外的所有索引都将发生变化。例如,如果您有一个列表 ,则将返回 。如果你这样做,那么会突然返回,因为现在将工作模6而不是模5。['a','b','c','d','e']get(7)cadd('f')get(7)bget


答案 2

你不能从ArrayList派生并沿着这些行重写get(int index)方法吗:

@Override
public E get(int index)
{
    if(index < 0)
        index = index + size();

    return super.get(index);
}

我错过了什么?

请注意,此实现不会将任意索引折叠到有效索引范围内,而只允许您从左侧和右侧正确处理列表(分别使用正索引和负索引,有点像Python)。


推荐