ArrayList和CircularArrayList之间的主要区别是什么

时间:2019-05-03 08:52:37

标签: java arraylist

我想构建自己的CircularArrayList,而不使用任何Java API。但是我已经在Internet上冲浪,无法找到和ArrayListCircularArrayList之间的基本区别。我总是以循环队列的定义结束。

这两种数据结构之间的基本区别是什么?

2 个答案:

答案 0 :(得分:0)

我没有直接解决这个问题,但是,我提供了有关如何使用Java实现循环数组的代码,

class CircularArray<T> implements Iterable<T> {


    private T[] items;
    private int head = 0;

    public CircularArray(int size) {    
        items = (T[]) new Object[size];
    }

    private int convert(int index) {

        if (index < 0) {
            index += items.length;
        }

        return (head + index) % items.length;
    }

    public void rotate(int shiftRight) {

        head = convert(shiftRight);
    }

    public T get(int i) {

        if (i < 0 || i >= items.length) {

            throw new java.lang.IndexOutOfBoundsException("Index " + i + " is out of bounds");
        }

        return items[convert(i)];
    }

    public void set(int i, T item) {
        items[convert(i)] = item;
    }

    public Iterator<T> iterator() {
        return new CircularArrayIterator<T>(this);
    }


    private class CircularArrayIterator<TI> implements Iterator<TI> {


        private int current = -1;
        private TI[] items;

        public CircularArrayIterator(CircularArray<TI> circularArray) {
            items = circularArray.items;
        }

        @Override
        public boolean hasNext() {
            return current < items.length - 1;
        }

        @Override
        public TI next() {
            current++;
            TI item = (TI) items[convert(current)];
            return item;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Remove is not supported by CircularArray");
        }
    }
}

现在,任务将使用此圆形数组数据结构来创建自定义的圆形ArrayList。但是,我不确定这在哪种情况下会有所帮助,因为我们无法像ArrayList一样扩展Array

答案 1 :(得分:0)

主要区别是:

  • 正确实现的 1 数组列表具有摊销的O(1)附加操作,但O(N)前面。

  • 一个圆形数组列表已摊销O(1)附加和前置操作。

  • 数组列表具有O(1)操作以删除最后一个元素。

  • 圆形数组列表具有O(1)操作,可删除第一个和最后一个元素。

因此,很显然,圆形数组列表的用例适合您要在列表的任一端添加和删除元素的情况。通常,通过将逻辑列表索引值映射为数组当前长度的模来完成此操作。例如

    public E get(int i) {
        // bounds checks ...
        return array[(first + i) mod array.length];
    }

对其他列表操作进行了类似的计算。由于这会使操作变慢,因此,仅在期望从头到尾进行添加和删除的情况下,才使用圆形数组列表。 / p>

  

我总是以循环队列的定义结束。

那是因为想法非常相似。循环数组列表可以用作循环队列。实际上,它是一个双端队列...出队。


1-需要注意的是,摊销O(1)仅在列表支持数组按数组大小成比例扩展时才会发生;例如长度加倍。