循环 ArrayList(扩展 ArrayList) [英] Circular ArrayList (extending ArrayList)

查看:21
本文介绍了循环 ArrayList(扩展 ArrayList)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

/*** 返回此列表中指定位置的元素.** @param index 要返回的元素的索引* @return 列表中指定位置的元素* @throws IndexOutOfBoundsException {@inheritDoc}*/公共 E 获取(整数索引){范围检查(索引);返回元素数据(索引);}

如果 index 是 -1,它应该得到索引为 ArrayList.size()-1 的元素,如果 index 是 ArrayList.size(),它应该得到索引为 0 的元素.

我想到的最简单的实现方法就是从 java.util 包中扩展 ArrayList 并覆盖 get(int index) 这样它就不会为上面的两个索引抛出 IndexOutOfBoundsException,而是将它们更改为我想.对于任何其他超出范围的索引,它会抛出 IndexOutOfBoundsException.

然而,由于 elementData(index) 访问了一个

私有瞬态对象[] elementData;

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

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

所以我有两个问题:

我怎样才能做到这一点?有没有办法在不将整个 ArrayList 类以及 AbstractCollection、Collection 和 Iterable 复制到我的程序中的情况下做到这一点?即使在我看来,这也是糟糕的设计.

如果我能以某种方式使它工作,还有什么我应该注意的吗?如果我进行上述更改,是否会按照我希望的方式更改类的行为,还是会发生任何其他不希望的行为更改?

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

import java.util.ArrayList;公共类 CircularArrayList扩展 ArrayList{private static final long serialVersionUID = 1L;公共 E 获取(整数索引){如果(索引== -1){索引 = 大小()-1;}否则如果(索引==大小()){指数 = 0;}返回 super.get(index);}}

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

解决方案

你不能从 ArrayList 派生并重写 get(int index) 方法:

@Override公共 E 获取(整数索引){如果(索引<0)索引 = 索引 + 大小();返回 super.get(index);}

我错过了什么?

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

So my program has a need of a type of circular ArrayList.

Only circular thing about it has to be the get(int index) method, this is the original:

    /**
     * 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);
    }

If index is -1 it should get the element with index ArrayList.size()-1 and if index is ArrayList.size(), it should get the element with index 0.

Simplest way of achieveing this which came to my mind is simply extending ArrayList from the java.util package and just overriding the get(int index) so it does not throw IndexOutOfBoundsException for the two indexes above, but change them to what I want. It would throw IndexOutOfBoundsException for any other index that is out of bounds.

However, since elementData(index) access a

private transient Object[] elementData;

I cannot make it work, because my class doesn't see it since it's private.

Also, I don't want to use any external libraries for this, simply because I think there are none that suit my needs, since I don't want a real circularArray, but only a part of it's functionality, rest of it being of the regular ArrayList.

So I have two questions:

How can I make this work? Is there a way to do it without copying the whole ArrayList class along with AbstractCollection, Collection and Iterable into my program? That seems like bad design even to me.

If I can somehow make it work, is there anything else I should watch for? If I make the changes described above, would that change the behaviour of the class only the way I want it to, or could there be any other undesired behaviour changes?

EDIT: Thanks for the answer, here's what I've done:

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);
    }
}

It will wrap around the ArrayList, but only by one. I want it to throw an exception if I try to access any other element but the first and the last with anything except their regular ArrayList indexes.

解决方案

Can't you derive from ArrayList and override the the get(int index) method along those lines:

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

    return super.get(index);
}

What am I missing?

Note that this implementation would not fold arbitrary indices into your valid index range but only allow you to properly address your list from both the left and right sides (with positive and negative indices respectively, a bit like in Python).

这篇关于循环 ArrayList(扩展 ArrayList)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆